# Troubleshooting

> Source-backed failure modes: plugin silent, no recall, embedding degrade, aggressive cleanup, offload slot/patch missing, Gateway circuit breaker, and recovery probes.

- Repository: TencentCloud/TencentDB-Agent-Memory
- GitHub: https://github.com/TencentCloud/TencentDB-Agent-Memory
- Human docs: https://grok-wiki.com/public/docs/tencentcloud-tencentdb-agent-memory-14fefdd76c97
- Complete Markdown: https://grok-wiki.com/public/docs/tencentcloud-tencentdb-agent-memory-14fefdd76c97/llms-full.txt

## Source Files

- `SKILL.md`
- `src/config.ts`
- `src/core/hooks/auto-recall.ts`
- `src/core/store/embedding.ts`
- `src/utils/ensure-hook-policy.ts`
- `hermes-plugin/memory/memory_tencentdb/client.py`
- `hermes-plugin/memory/memory_tencentdb/tests/test_memory_tencentdb_recovery.py`
- `scripts/bugfix-20260423/BUGFIX-20260423-SOP.md`

---

---
title: "Troubleshooting"
description: "Source-backed failure modes: plugin silent, no recall, embedding degrade, aggressive cleanup, offload slot/patch missing, Gateway circuit breaker, and recovery probes."
---

Failure modes for **TencentDB Agent Memory** (`@tencentdb-agent-memory/memory-tencentdb`, plugin id `memory-tencentdb`) surface on three runtime paths: the OpenClaw plugin (`index.ts` / `TdaiCore`), the context-offload slot (`offload.enabled` + `plugins.slots.contextEngine`), and the Hermes Gateway sidecar (`MemoryTencentdbProvider` + HTTP client on port `8420`). Logs use the historical tag `[memory-tdai]`; on-disk data stays under `memory-tdai` even after the package rename.

## Symptom matrix

| Symptom | Likely surface | First probe |
| --- | --- | --- |
| No `[memory-tdai]` logs after install | Plugin not enabled / Gateway not restarted | `openclaw.json` + gateway restart |
| Capture/hooks never fire on OC ≥ 2026.4.23 | `hooks.allowConversationAccess` blocked | Policy field + optional bugfix script |
| Turns run but no memory injection | Recall path | `recall.*`, score threshold, strategy fallback |
| Only keyword hits / no vectors | Embedding quadruplet or store degrade | `[EMBEDDING CONFIG ERROR]`, `vectors.db` |
| History vanishes after a few days | Retention / aggressive cleanup | `l0l1RetentionDays`, `allowAggressiveCleanup` |
| Offload never compresses tool output | Slot or `after-tool-call` patch | `contextEngine` + patch script |
| Hermes tools empty / “circuit breaker tripped” | Gateway sidecar | `/health`, breaker cooldown, watchdog |

## Plugin silent (no logs, no capture)

### Enablement and restart

Plugin registration always parses `api.pluginConfig` and logs at `[memory-tdai]`. If that tag never appears:

1. Confirm install: `openclaw plugins install @tencentdb-agent-memory/memory-tencentdb` (or `plugins update memory-tencentdb`).
2. Enable in `~/.openclaw/openclaw.json` (or `OPENCLAW_CONFIG_PATH`):

```json
{
  "memory-tencentdb": {
    "enabled": true
  }
}
```

3. Restart: `openclaw gateway restart`.
4. Expect log prefix `[memory-tdai]` and data under `{OPENCLAW_STATE_DIR or ~/.openclaw}/memory-tdai/` (`conversations/`, `records/`, `scene_blocks/`, `vectors.db`).

Zero-config defaults leave `capture`, `extraction`, and `recall` enabled; `offload.enabled` defaults to `false`.

### Silent hook block (`allowConversationAccess`)

On OpenClaw **v2026.4.23+**, non-bundled plugins without `hooks.allowConversationAccess: true` can have conversation hooks (`agent_end`, related session hooks) blocked while the plugin still “loads.”

Auto-patch (`ensurePluginHookPolicy`):

- Runs only on gateway-start processes (skips `plugins install|doctor|config|…`).
- Applies only when host version ≥ **2026.4.24** (`HOOK_POLICY_MIN_VERSION`); unparsable/missing `api.runtime.version` → **no** auto-patch (safe for older hosts).
- Writes:

```json
{
  "plugins": {
    "entries": {
      "memory-tencentdb": {
        "hooks": {
          "allowConversationAccess": true
        }
      }
    }
  }
}
```

- Prefers SDK `mutateConfigFile` with `afterWrite: { mode: "restart" }`; falls back to a manual write and warns that **restart is required**.
- If config uses `$include`, logs a manual-edit warning instead of rewriting.

**OpenClaw 2026.4.23 only:** Zod `.strict()` rejected the field (Issue #73806). Use the repo SOP:

```bash
openclaw gateway stop
bash scripts/bugfix-20260423/bugfix-20260423.sh
# verify allowConversationAccess under plugins.entries.memory-tencentdb.hooks
# verify dist schema contains allowConversationAccess once
openclaw gateway run
```

### Verification signals

| Signal | Meaning |
| --- | --- |
| `[memory-tdai] [hook-policy] ✅ …` | Policy patched |
| `[memory-tdai] Config parsed: capture=…, recall=…` | Plugin registered |
| Data dir created under `memory-tdai/` | Init path ran |
| No logs after restart | Wrong config path / plugin not loaded / host not restarted |

## No recall

Auto-recall registers only when `recall.enabled` is true (`before_prompt_build` → `core.handleBeforeRecall` / `performAutoRecall`).

### Checklist

| Check | Default / rule | Failure effect |
| --- | --- | --- |
| `recall.enabled` | `true` | Hook never registered |
| User prompt text | Non-empty | Skip L1 search (persona/scene may still inject) |
| Sanitized query length | ≥ 2 chars after `sanitizeText` | Empty search result |
| `recall.scoreThreshold` | `0.3` | Hits below threshold dropped |
| `recall.maxResults` | `5` | Caps injected lines |
| `recall.timeoutMs` | `5000` | Timeout → **skip injection** (warn), non-blocking |
| `recall.strategy` | `hybrid` | If embedding unavailable → **keyword** fallback |
| Session filter | `capture.excludeAgents` | Matched agents skip recall |
| Exceptions | — | Logged + `error_degradation` → `degradedTo: "no_recall"` |

Log patterns:

- `Recall complete (…ms), no context to inject` — ran, nothing to inject (threshold, empty index, or budget).
- `⚠️ Recall timed out after …ms — skipping memory injection` — protect latency over recall.
- `Strategy "hybrid"|"embedding" requested but EmbeddingService not available, falling back to keyword` — vector path offline.
- Keyword path needs FTS5; if FTS unavailable, keyword returns empty (no full-table O(N) fallback).

Smoke: multi-turn with memorable facts, then call tools `tdai_memory_search` / `tdai_conversation_search` and re-open a session to observe injection.

## Embedding degrade

### Config-time disable (non-throwing)

`parseConfig` does **not** fail the plugin when remote embedding is incomplete. It sets `embedding.configError`, forces `embedding.enabled = false`, and logs at register time:

`[memory-tdai] [EMBEDDING CONFIG ERROR] …`

| `embedding.provider` | Behavior |
| --- | --- |
| `"none"` (default) | Vectors off; `dimensions` forced to `0` (no vec0 tables until a real provider is set) |
| `"local"` | Treated as disabled at config entry; `configError` tells you to use a remote provider |
| Remote (`openai`, `deepseek`, …) | Requires **apiKey + baseUrl + model + dimensions** (all present, dimensions &gt; 0). Any missing field → disabled + detailed `Missing: …` |
| `"qclaw"` | Same quadruplet **plus** `proxyUrl` |

`sendDimensions` defaults to `true` (OpenAI Matryoshka). Self-hosted models that reject `dimensions` (e.g. BGE-M3 HTTP 400) need `"sendDimensions": false`.

### Runtime store degrade

`VectorStore` (`sqlite`) can enter `degraded = true` if sqlite-vec load/init fails. Then upserts/searches become safe no-ops; logs include `VectorStore entering degraded mode` / `[L1-search] SKIPPED (degraded mode)`. Gateway `GET /health` reports:

```json
{
  "status": "ok" | "degraded",
  "stores": {
    "vectorStore": true | false,
    "embeddingService": true | false
  }
}
```

`status` is `degraded` when `core.getVectorStore()` is missing. `TdaiCore` continues with JSONL / non-vector paths when store init fails.

### Factory behavior

SQLite path creates a remote `EmbeddingService` only when `embedding.enabled && provider !== "local" && apiKey`. Otherwise vector search is unavailable and hybrid/embedding strategies fall back to keyword.

## Aggressive cleanup

### Retention gate

From `capture.l0l1RetentionDays` + `capture.allowAggressiveCleanup` (default `false`):

| `l0l1RetentionDays` | `allowAggressiveCleanup` | Effective cleaner |
| --- | --- | --- |
| `≤ 0` | any | Disabled (`retentionDays` undefined) |
| `≥ 3` | any | Enabled with that many days |
| `1` or `2` | `false` | **Forced off** (treated as invalid/dangerous) |
| `1` or `2` | `true` | Enabled (aggressive) |

Daily schedule uses `capture.cleanTime` (default `"03:00"`).

### Safety guards (even when enabled)

| Guard | Value | Effect |
| --- | --- | --- |
| Min retain L0 | 50 | Skip L0 delete if total ≤ 50 |
| Min retain L1 | 20 | Skip L1 delete if total ≤ 20 |
| SQLite ratio block | &gt; 80% of rows would expire in one pass | Log `BLOCKED: would delete … exceeds 80% safety threshold`, delete **0** |
| Degraded store | `isDegraded()` | `deleteExpired*` skipped |

If history “disappears,” verify you did not set retention to 1–2 with `allowAggressiveCleanup: true`, and inspect cleaner logs: `[memory-tdai][cleaner]`, `cleaner_summary`, `BLOCKED`.

## Offload slot / patch missing

Context offload is independent of long-term memory defaults (`offload.enabled` default `false`).

### Required wiring

1. **Config**

```json
{
  "memory-tencentdb": {
    "config": {
      "offload": {
        "enabled": true
      }
    }
  },
  "plugins": {
    "slots": {
      "contextEngine": "memory-tencentdb"
    }
  }
}
```

Without `plugins.slots.contextEngine = "memory-tencentdb"`, OpenClaw will not route context-engine work to this plugin.

2. **Runtime patch** — `scripts/openclaw-after-tool-call-messages.patch.sh` (also best-effort `postinstall` in `package.json`). Idempotent; re-run after OpenClaw upgrades. Without it, after-tool-call message offload/recovery is incomplete.

3. **Helper** — `scripts/setup-offload.sh` applies the patch, sets the slot, and toggles `offload.enabled`. Patch failure **aborts** enable.

4. **Data** — default root `~/.openclaw/context-offload` (override with `offload.dataDir`).

If `cfg.offload.enabled` is true, `registerOffload` runs; failures are logged as `Offload module registration failed` without taking down memory.

## Gateway circuit breaker (Hermes)

Hermes provider `MemoryTencentdbProvider` talks to the Node Gateway sidecar via `MemoryTencentdbSdkClient` (default `http://127.0.0.1:8420`, timeout 10s).

### Breaker and recovery constants

| Constant | Value | Role |
| --- | --- | --- |
| `_BREAKER_THRESHOLD` | 5 | Consecutive failures trip breaker |
| `_BREAKER_COOLDOWN_SECS` | 60 | Pause business calls while open |
| `_RECOVER_COOLDOWN_SECS` | 15 | Throttle request-path `ensure_running` |
| `_WATCHDOG_INTERVAL_SECS` | 10 | Background health / resurrect |

On trip: log `memory-tencentdb circuit breaker tripped after N failures. Pausing for 60s.` Tool path may return JSON error `memory-tencentdb Gateway temporarily unavailable (circuit breaker open).`

### Recovery model

```text
Request path                          Background
────────────                          ──────────
prefetch / capture / tools
  │
  ├─ _ensure_alive_for_request()
  │    if available → proceed
  │    if breaker open → empty/disable (no recover storm)
  │    else → _try_recover_gateway() (15s throttle)
  │
  └─ on HTTP errors → _record_failure()
       after 5 → open breaker 60s

Watchdog every 10s:
  process alive + available → noop
  /health ok but available=false → reattach client, clear breaker
  down → _try_recover_gateway(bypass_cooldown=True)
```

Known deadlock class (covered by tests): `_gateway_available` stuck `False` while every request short-circuited before the failure path. Mitigations: **lazy probe** on request guards + **watchdog** even with no traffic.

Auth: client may send `Authorization: Bearer …` from `MEMORY_TENCENTDB_GATEWAY_API_KEY` or `TDAI_GATEWAY_API_KEY`. Mismatch with Gateway secret → HTTP failures that count toward the breaker.

### Hermes-side symptoms

| Message / behavior | Action |
| --- | --- |
| Gateway not available at startup | Set `MEMORY_TENCENTDB_GATEWAY_CMD` or ensure auto-discovery finds `src/gateway/server.ts`; check `~/.hermes/logs/memory_tencentdb/gateway.stderr.log` |
| Search tools missing from LLM | `get_tool_schemas()` is `[]` until Gateway reachable **or** `MEMORY_TENCENTDB_GATEWAY_CMD` / `PORT` set |
| Circuit breaker tripped | Inspect sidecar health/logs; wait cooldown or fix root cause so watchdog can clear |
| Capture backlog | ≥ 4 in-flight sync threads — Gateway slow/hung |

## Recovery probes

Use these as ordered ops checks, not product APIs.

### OpenClaw plugin

```bash
openclaw --version    # need >= 2026.3.13
node -v               # need >= 22.16.0
openclaw gateway restart

# Config
# - memory-tencentdb enabled
# - plugins.entries.memory-tencentdb.hooks.allowConversationAccess == true (OC >= 2026.4.23/24)

# Logs: [memory-tdai], [hook-policy], [EMBEDDING CONFIG ERROR], before_prompt_build Recall complete
# Data: $OPENCLAW_STATE_DIR/memory-tdai or ~/.openclaw/memory-tdai
```

### Offload

```bash
bash scripts/openclaw-after-tool-call-messages.patch.sh
# or: bash scripts/setup-offload.sh
# Confirm plugins.slots.contextEngine == memory-tencentdb and offload.enabled
# Data: ~/.openclaw/context-offload
```

### Gateway / Hermes

```bash
# Standalone or hermes mode (see gateway-control page for full flags)
memory-tencentdb-ctl status
memory-tencentdb-ctl health   # GET /health → status ok|degraded

# Env pins
# MEMORY_TENCENTDB_GATEWAY_CMD, MEMORY_TENCENTDB_GATEWAY_HOST, MEMORY_TENCENTDB_GATEWAY_PORT
# MEMORY_TENCENTDB_GATEWAY_API_KEY / TDAI_GATEWAY_API_KEY
# MEMORY_TENCENTDB_LOG_DIR
```

`GET /health` response shape: `status`, `version`, `uptime`, `stores.vectorStore`, `stores.embeddingService`.

### Package diagnostics

```bash
bash scripts/export-diagnostic.sh [output-dir]
```

Packages redacted config, gateway logs, and `memory-tdai` data for local-only analysis.

### Automated recovery tests (Hermes)

`hermes-plugin/memory/memory_tencentdb/tests/test_memory_tencentdb_recovery.py` covers:

- Watchdog start, death detection, resurrect, external restart reattach
- Circuit breaker reset on recovery
- Lazy probe self-heal on `prefetch` / tools / `sync_turn`
- Open breaker still short-circuits without respawn storm

## Related pages

<CardGroup>
  <Card title="Installation" href="/installation">
    Prerequisites, install/update, postinstall patch behavior.
  </Card>
  <Card title="Quickstart" href="/quickstart">
    Zero-config enable, restart, success signals, smoke tools.
  </Card>
  <Card title="Enable context offload" href="/enable-offload">
    offload.enabled, contextEngine slot, after-tool-call patch.
  </Card>
  <Card title="Configure storage" href="/configure-storage">
    sqlite vs tcvdb, embedding quadruplets, store health.
  </Card>
  <Card title="Configuration reference" href="/configuration-reference">
    Full schema: recall, embedding, capture retention, offload.
  </Card>
  <Card title="Gateway control" href="/gateway-control">
    memory-tencentdb-ctl start/stop/status/health/logs.
  </Card>
  <Card title="Gateway HTTP API" href="/gateway-http-api">
    /health, /recall, /capture, search and seed endpoints.
  </Card>
  <Card title="Export diagnostics" href="/export-diagnostics">
    export-diagnostic.sh package layout and privacy notes.
  </Card>
  <Card title="Install on Hermes" href="/install-hermes">
    Provider install, sidecar supervision, config keys.
  </Card>
  <Card title="Data directories" href="/data-directories">
    memory-tdai, context-offload, Hermes MEMORY_TENCENTDB_ROOT trees.
  </Card>
</CardGroup>
