openclaw - 💡(How to fix) Fix Telegram plugin-state hits per-plugin cap and locks out new writes (v2026.5.26)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

In v2026.5.26 the telegram plugin became unable to write any new entries to its telegram.message-cache plugin-state namespace shortly after install, repeatedly failing with PluginStateStoreError: Plugin state for telegram exceeds the 1000 live row limit. The error reaches the message handler as Something went wrong while processing your message. Please try again. so every inbound after the lockup gets a stock failure reply.

Root cause is a structural off-by-one between the per-namespace maxEntries the telegram plugin requests and the hard per-plugin MAX_ENTRIES_PER_PLUGIN, plus the way the post-register eviction is gated.

Error Message

In v2026.5.26 the telegram plugin became unable to write any new entries to its telegram.message-cache plugin-state namespace shortly after install, repeatedly failing with PluginStateStoreError: Plugin state for telegram exceeds the 1000 live row limit. The error reaches the message handler as Something went wrong while processing your message. Please try again. so every inbound after the lockup gets a stock failure reply.

Root Cause

Root cause is a structural off-by-one between the per-namespace maxEntries the telegram plugin requests and the hard per-plugin MAX_ENTRIES_PER_PLUGIN, plus the way the post-register eviction is gated.

Fix Action

Fix / Workaround

Field workarounds (in case anyone hits this before a fix lands)

Code Example

function enforcePostRegisterLimits(params) {
  const namespaceCount = countRow(
    params.store.statements.countLiveNamespace.get(
      params.pluginId, params.namespace, params.now,
    ),
  );
  if (namespaceCount > params.maxEntries) {
    params.store.statements.deleteOldestNamespace.run(
      params.pluginId, params.namespace, params.protectedKey, params.now,
      namespaceCount - params.maxEntries,
    );
  }
  if (countRow(
    params.store.statements.countLivePlugin.get(params.pluginId, params.now),
  ) > MAX_ENTRIES_PER_PLUGIN) {
    throw createPluginStateError({
      code: "PLUGIN_STATE_LIMIT_EXCEEDED",
      operation: "register",
      message: `Plugin state for ${params.pluginId} exceeds the ${MAX_ENTRIES_PER_PLUGIN} live row limit.`,
      path: params.store.path,
    });
  }
}

---

DELETE FROM plugin_state_entries
  WHERE rowid IN (
    SELECT rowid FROM plugin_state_entries
    WHERE plugin_id = 'telegram' AND namespace = 'telegram.message-cache'
    ORDER BY created_at ASC LIMIT N
  );
RAW_BUFFERClick to expand / collapse

Summary

In v2026.5.26 the telegram plugin became unable to write any new entries to its telegram.message-cache plugin-state namespace shortly after install, repeatedly failing with PluginStateStoreError: Plugin state for telegram exceeds the 1000 live row limit. The error reaches the message handler as Something went wrong while processing your message. Please try again. so every inbound after the lockup gets a stock failure reply.

Root cause is a structural off-by-one between the per-namespace maxEntries the telegram plugin requests and the hard per-plugin MAX_ENTRIES_PER_PLUGIN, plus the way the post-register eviction is gated.

Environment

  • openclaw 2026.5.26
  • Telegram plugin enabled (bundled)
  • Reproducible after openclaw doctor --fix migrates the legacy file-based message cache into the plugin-state SQLite store. With a chatty bot you can hit the same state organically once the namespace fills.

Repro

  1. Run doctor --fix on a host with a populated legacy telegram message cache so that the migrated entries land in telegram.message-cache. In the field this fills the namespace to 999 entries (one slot reserved by an unrelated path).
  2. Telegram has a co-tenant namespace telegram.bot-info-cache with 1 live row (24h TTL).
  3. Send any telegram message to the bot.
  4. Plugin attempts to register a new telegram.message-cache entry → write fails with PluginStateStoreError: Plugin state for telegram exceeds the 1000 live row limit. Bot replies with the canned Something went wrong....

Expected

enforcePostRegisterLimits evicts the oldest entry from the over-full namespace and lets the write proceed within the per-plugin total cap.

Actual

Eviction is gated on namespaceCount > maxEntries, with maxEntries == MAX_ENTRIES_PER_PLUGIN == 1000. Because the telegram plugin also owns a second namespace with a live row, the plugin total reaches the hard cap before the namespace count strictly exceeds its declared maximum. The write transaction throws before any eviction runs.

Root cause (code refs)

In the post-register limit enforcement:

function enforcePostRegisterLimits(params) {
  const namespaceCount = countRow(
    params.store.statements.countLiveNamespace.get(
      params.pluginId, params.namespace, params.now,
    ),
  );
  if (namespaceCount > params.maxEntries) {
    params.store.statements.deleteOldestNamespace.run(
      params.pluginId, params.namespace, params.protectedKey, params.now,
      namespaceCount - params.maxEntries,
    );
  }
  if (countRow(
    params.store.statements.countLivePlugin.get(params.pluginId, params.now),
  ) > MAX_ENTRIES_PER_PLUGIN) {
    throw createPluginStateError({
      code: "PLUGIN_STATE_LIMIT_EXCEEDED",
      operation: "register",
      message: `Plugin state for ${params.pluginId} exceeds the ${MAX_ENTRIES_PER_PLUGIN} live row limit.`,
      path: params.store.path,
    });
  }
}

With these constants:

  • TELEGRAM_MESSAGE_CACHE_PERSISTENT_MAX_MESSAGES = 1e3 (passed as maxEntries from the telegram plugin's openKeyedStore call)
  • MAX_ENTRIES_PER_PLUGIN = 1e3 (hard limit in plugin-state-store)

For a write that lifts telegram.message-cache to exactly maxEntries while telegram.bot-info-cache holds one live row:

  1. upsertEntry lands the new row.
  2. namespaceCount is 1000. 1000 > 1000 is false → no eviction.
  3. countLivePlugin is 1001. 1001 > 1000 is true → throw, transaction rolls back.

The plugin can never reach its own declared namespace maximum as long as any co-tenant namespace has a single live entry, because the plugin-wide cap equals the namespace cap.

Suggested fixes (any one closes the trap)

  1. Eviction trigger uses >= instead of >, so a write that hits namespaceCount == maxEntries evicts the oldest peer before the per-plugin check, OR over-evict by one when the per-plugin total would otherwise exceed the hard cap.
  2. Reserve headroom in the telegram plugin: call openKeyedStore with maxEntries: MAX_ENTRIES_PER_PLUGIN - reservedForOtherNamespaces. Today the magic number is 998 (1000 - 1 bot-info live row - 1 protected key).
  3. Reorder enforcement: when the per-plugin total exceeds the cap, evict from the largest namespace first instead of throwing.

(1) is the least invasive — the eviction primitive already exists and can take a delta-by-one bump.

Field workarounds (in case anyone hits this before a fix lands)

  • Recovery from already-stuck state: prune the oldest message-cache rows directly:
    DELETE FROM plugin_state_entries
    WHERE rowid IN (
      SELECT rowid FROM plugin_state_entries
      WHERE plugin_id = 'telegram' AND namespace = 'telegram.message-cache'
      ORDER BY created_at ASC LIMIT N
    );
  • Long-term: lower the namespace-cap constant in the installed bundle (TELEGRAM_MESSAGE_CACHE_PERSISTENT_MAX_MESSAGES) to 998. Must be reapplied after every npm install.

Privacy

No host, IP, OS, account, or message content included; only the structural facts and code references.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Telegram plugin-state hits per-plugin cap and locks out new writes (v2026.5.26)