openclaw - ✅(Solved) Fix session_status throws "Unknown sessionKey: current" for channel-plugin agents (~4s wasted per turn) [2 pull requests, 1 comments, 2 participants]

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…
GitHub stats
openclaw/openclaw#74141Fetched 2026-04-30 06:28:01
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
cross-referenced ×3commented ×1

The session_status tool's docstring (tool-description-presets.ts:63) advises agents to pass sessionKey="current" universally, but the resolver only honors the alias for first-party UI client ids. For agents driven by a channel plugin (Slack, Discord, Scope, etc.), the literal "current" falls through every resolution path and the tool throws Unknown sessionKey: current. The agent retries with a constructed key, that fails too, and only then produces a final reply.

Root Cause

The session_status tool's docstring (tool-description-presets.ts:63) advises agents to pass sessionKey="current" universally, but the resolver only honors the alias for first-party UI client ids. For agents driven by a channel plugin (Slack, Discord, Scope, etc.), the literal "current" falls through every resolution path and the tool throws Unknown sessionKey: current. The agent retries with a constructed key, that fails too, and only then produces a final reply.

Fix Action

Fixed

PR fix notes

PR #74142: fix(agents/tools): resolve sessionKey=current for channel-plugin clients

Description (problem / solution / changelog)

Summary

  • Problem: The session_status tool's docstring (tool-description-presets.ts:63) tells agents universally to pass sessionKey="current", but resolveCurrentSessionClientAlias only honors the alias for first-party UI client ids (TUI, CLI, WEBCHAT_UI, CONTROL_UI, MACOS_APP, IOS_APP, ANDROID_APP). Channel-plugin clients (Slack, Discord, Scope, ...) fall through, the literal "current" is never resolved to the requester, the literal-current store lookup and sessions.resolve("current") both find nothing, and the tool throws Unknown sessionKey: current. The agent retries with a constructed key, that fails too, and only then produces a final reply — costing ~4s per turn on date/time / model-status queries.
  • Why it matters: The system prompt (system-prompt.ts:827) directs agents to call session_status for date/time questions. Every such question on a channel-plugin agent burns ~4s of failed tool calls before the agent gives up and answers from internal state. Repro and gateway log slice in #74141.
  • What changed: Added a final fallback in session-status-tool.ts: when the literal-current store lookup AND resolveSessionReference both return nothing matching, treat "current" as the requester's own session. Sets resolvedViaImplicitCurrentFallback = true so visibility-target-as-self handling at :469-475 still works.
  • What did NOT change (scope boundary): The existing prefer-literal-session-named-"current" feature documented by prefers a literal current session key in session_status and resolves a literal current sessionId in session_status — preserved by positioning the new fallback AFTER those paths. resolveCurrentSessionClientAlias itself — untouched, so resolveSessionReference's strict-alias semantics for non-UI clients are unchanged. The CURRENT_SESSION_CLIENT_ALIAS_IDS set — untouched. Other tools that take a sessionKey param (sessions_history, sessions_send, sessions_spawn, subagents) — those have their own resolution paths and aren't affected by this PR (separate fix if/when they hit the same class of issue).

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Skills / tool execution

Linked Issue/PR

  • Closes #74141
  • This PR fixes a bug or regression

Root Cause

resolveCurrentSessionClientAlias was designed for the case where a UI/CLI client passes its own client id (e.g., "openclaw-tui") as the sessionKey and the resolver translates that to the requester key. The literal alias "current" was not part of that contract — agents passing "current" were expected to be served by the deeper resolveSessionReferencesessions.resolve("current") path, which works if a real session is keyed literally "current" in the gateway.

That assumption holds for first-party UI clients (where the ACP gateway registers a session keyed by the client's session id and "current" happens to match in practice for TUI/CLI flows) but doesn't hold for channel-plugin clients. The docstring Use sessionKey="current" for the current session was added universally, ahead of the implementation actually supporting it universally — leaving channel-plugin agents to discover the gap at runtime.

Tests

  • Added resolves sessionKey=current for a channel-plugin session via implicit fallback in src/agents/openclaw-tools.session-status.test.ts. Uses a channel-style requester key (agent:main:scope:scopy:direct:scopy) and asserts details.sessionKey is the requester key.
  • All 116 existing tests in sessions-resolution.test.ts + openclaw-tools.session-status.test.ts pass unchanged.

Verification

$ pnpm vitest run \
    src/agents/tools/sessions-resolution.test.ts \
    src/agents/openclaw-tools.session-status.test.ts
 Test Files  4 passed (4)
      Tests  116 passed (116)

Changed files

  • src/agents/openclaw-tools.session-status.test.ts (modified, +23/-0)
  • src/agents/tools/session-status-tool.ts (modified, +23/-0)

PR #72306: fix(agents/tools): resolve sessionKey="current" for channel-plugin agents

Description (problem / solution / changelog)

Summary

  • Problem: session_status's docstring tells agents to pass sessionKey="current", but the resolver only treats that alias as "the requester" for first-party UI clients (TUI, CLI, web/mobile). Channel-plugin agents (Slack, Discord, Scope, ...) hit Unknown sessionKey: current, retry with their constructed key (also misses the store), and burn ~4s per turn before giving up.
  • Why it matters: The system prompt routes date/time and several status questions through session_status. Every one of those was paying the 4s tax on channel-plugin agents.
  • What changed: After every existing fallback misses, treat sessionKey="current" as the requester's own session and return a status card backed by a minimal synthesized entry. The fallback is the very last step in the chain, gated strictly on the literal "current".
  • What did NOT change: resolveCurrentSessionClientAlias and CURRENT_SESSION_CLIENT_ALIAS_IDS are untouched. Existing precedence for literal sessions/sessionIds named "current" is preserved (their tests still pass byte-identical). Other tools that take a sessionKey aren't touched.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Skills / tool execution

Linked Issue/PR

  • Closes #74141
  • This PR fixes a bug or regression

Root Cause

  • Root cause: The docstring promised "current" worked universally, but the resolver only mapped it to the requester for a hard-coded set of UI client ids. Channel-plugin requesters whose session has not been written to the store yet have nothing to match.
  • Missing detection / guardrail: No test exercised an unstored channel-style requester. Every existing current-related test happened to use a stored requester key.
  • Contributing context (if known): resolveCurrentSessionClientAlias was originally for translating UI client labels like openclaw-tui into the requester key. The literal "current" was assumed to be served by the deeper sessions.resolve("current") path, which only works for first-party flows.

Regression Test Plan

  • Coverage level that should have caught this:
    • Unit test
  • Target test or file: src/agents/openclaw-tools.session-status.test.ts
  • Scenario the test should lock in: channel-style requester key + empty store + sessionKey: "current" resolves to the requester key instead of throwing.
  • Why this is the smallest reliable guardrail: the existing test mocks already cover store, gateway resolve, and status-text rendering, so one new it(...) exercises the full path.
  • Tests added in this PR:
    • resolves sessionKey=current for a channel-plugin requester via implicit fallback — the regression.
    • does not synthesize a current fallback for unknown non-literal session keys — gate proof; arbitrary unknown keys still throw.

User-visible / Behavior Changes

For channel-plugin agents whose session hasn't been persisted yet, session_status with sessionKey="current" now returns a usable status card (defaults from config, no transcript usage) instead of throwing. No change for agents whose session is already in the store, no change for first-party UI clients.

Diagram

N/A

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No. The synthesized entry is keyed to the requester's own key and goes through the existing visibilityGuard.check with resolvedViaImplicitCurrentFallback = true (treat-as-self) — the same path the existing implicit-default-direct fallback uses.

Repro + Verification

Environment

  • OS: Linux x64
  • Runtime: Node 22+
  • Channel: any channel-plugin agent with a channel-style requester key (reporter confirmed against Scope, agent:scopy:scope:scopy:direct:scopy)

Steps

  1. Run a gateway with a channel-plugin agent whose requester key is channel-style.
  2. Send a message that triggers session_status (e.g. "What day is it today?").
  3. Watch the gateway logs.

Expected

  • session_status returns a status card on the first call, no retry loop.

Actual (before)

  • Throws Unknown sessionKey: current, retries with the constructed key, throws again, ~4s wasted per turn.

Evidence

  • Failing test/log before + passing after — pnpm test src/agents/openclaw-tools.session-status.test.ts src/agents/tools/sessions-resolution.test.ts → 60/60 passing. The new regression test fails on main with Unknown sessionKey: current and passes with this patch.
  • Trace/log snippets — see #74141 for the gateway log slice.

Human Verification

  • Verified scenarios:
    • Channel-style requester key + empty store + sessionKey: "current" → returns status card backed by the requester key.
    • Channel-style requester key + empty store + non-"current" key → still throws Unknown sessionId.
    • Literal session named current in the store → still preferred over the synthetic fallback.
    • Literal sessionId "current" in the store → still preferred.
    • Subagent requester + "current" → still binds to the subagent session.
    • First-party UI alias (openclaw-tui) → unchanged.
  • Edge cases checked: empty/blank storeScopedRequesterKey short-circuits the fallback to null so the original throw still fires.
  • What I did not verify: live end-to-end on a real channel plugin (no local Scope/Slack/Discord environment). The unit test covers the exact resolution chain the live repro hit.

Changed files

  • src/agents/openclaw-tools.session-status.test.ts (modified, +93/-0)
  • src/agents/tools/session-status-tool.ts (modified, +47/-3)

Code Example

05:52:15.252  ⇄ res ✗ sessions.resolve INVALID_REQUEST: No session found: current
05:52:15.528  ⇄ res ✗ sessions.resolve INVALID_REQUEST: No session found: current
05:52:15.531  [tools] session_status failed: Unknown sessionKey: current
05:52:19.278  [tools] session_status failed: Unknown sessionKey: agent:scopy:scope:scopy:direct:scopy

---

05:52:04.850  [agent/embedded] [hooks] provider overridden to scope    ← turn starts
05:52:15.106  ⇄ res ✓ sessions.list 137ms
05:52:15.252  ⇄ res ✗ sessions.resolve INVALID_REQUEST: No session found: current
05:52:15.528  ⇄ res ✗ sessions.resolve INVALID_REQUEST: No session found: current
05:52:15.531  [tools] session_status failed: Unknown sessionKey: current
05:52:19.278  [tools] session_status failed: Unknown sessionKey: agent:scopy:scope:scopy:direct:scopy
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash) — performance + UX (~4s wasted per affected turn, agent visibly retries).

Beta release blocker

No

Summary

The session_status tool's docstring (tool-description-presets.ts:63) advises agents to pass sessionKey="current" universally, but the resolver only honors the alias for first-party UI client ids. For agents driven by a channel plugin (Slack, Discord, Scope, etc.), the literal "current" falls through every resolution path and the tool throws Unknown sessionKey: current. The agent retries with a constructed key, that fails too, and only then produces a final reply.

Steps to reproduce

  1. Run any gateway with a channel-plugin-driven agent whose requester session key is channel-style (e.g. agent:<agent>:<channel-id>:<agent>:direct:<peer>). Confirmed against 2026.4.26-f53b52ad6d21 on a Scope-channel agent (agent:scopy:scope:scopy:direct:scopy).
  2. Send the agent a message that triggers session_status — e.g. "What day is it today?" (the system prompt at system-prompt.ts:827 directs agents to use session_status for date/time questions).
  3. Observe in the gateway logs:
05:52:15.252  ⇄ res ✗ sessions.resolve INVALID_REQUEST: No session found: current
05:52:15.528  ⇄ res ✗ sessions.resolve INVALID_REQUEST: No session found: current
05:52:15.531  [tools] session_status failed: Unknown sessionKey: current
05:52:19.278  [tools] session_status failed: Unknown sessionKey: agent:scopy:scope:scopy:direct:scopy

Expected behavior

sessionKey="current" should resolve to the requester's own session, regardless of whether the requester is a UI client or a channel-plugin client. That's what the universally-applied tool docstring promises.

Actual behavior

  • resolveCurrentSessionClientAlias (src/agents/tools/sessions-resolution.ts:62-83) only returns the requester key when normalizeGatewayClientId(params.key) matches one of CURRENT_SESSION_CLIENT_ALIAS_IDS (TUI, CLI, WEBCHAT_UI, CONTROL_UI, MACOS_APP, IOS_APP, ANDROID_APP). The literal string "current" doesn't match any gateway client id, so the alias path returns undefined and requestedKeyRaw stays as "current".
  • resolveSessionEntry with keyRaw="current", includeAliasFallback: false finds nothing.
  • resolveSessionReference calls sessions.resolve with key:"current" → fails (no session named "current"). Falls through to gateway lookup with the requester key, returns {ok: true, key: requesterInternalKey, resolvedViaSessionId: false}. But session-status-tool only consumes that result if resolvedViaSessionId === true — channel-plugin requesters resolve via key-alias path, not sessionId path, so this branch is skipped.
  • The if (!resolved && requestedKeyRaw === "current") retry at session-status-tool.ts:432 still uses keyRaw="current", finds nothing.
  • The listImplicitDefaultDirectFallbackKeys branch at :443 only runs when requestedKeyParam === undefined — but here requestedKeyParam = "current", so this branch is skipped.
  • Throws Unknown sessionKey: current at :465.

The agent then retries with its own constructed key, hits the same store-miss path, and gets Unknown sessionKey: agent:scopy:scope:scopy:direct:scopy (separate channel-session-store-registration issue, not this report).

Environment

  • OpenClaw 2026.4.26-f53b52ad6d21
  • Node v24.14.0
  • Linux x64 (Elestio-hosted Docker container)
  • Channel plugin: scope-openclaw 0.35.5

Logs / evidence

See repro output above. Gateway log slice for the affected turn:

05:52:04.850  [agent/embedded] [hooks] provider overridden to scope    ← turn starts
05:52:15.106  ⇄ res ✓ sessions.list 137ms
05:52:15.252  ⇄ res ✗ sessions.resolve INVALID_REQUEST: No session found: current
05:52:15.528  ⇄ res ✗ sessions.resolve INVALID_REQUEST: No session found: current
05:52:15.531  [tools] session_status failed: Unknown sessionKey: current
05:52:19.278  [tools] session_status failed: Unknown sessionKey: agent:scopy:scope:scopy:direct:scopy

That's ~4s of failed tool calls between the first failure (15.531) and the next (19.278) — pure agent-retry latency, no productive work.

Proposed fix

Add a final fallback in session-status-tool.ts's resolution chain: when the literal-current store lookup AND the gateway sessions.resolve("current") both find nothing matching, treat "current" as the requester's own session.

Position the fallback AFTER the existing literal-current paths so the prefer-literal-session-named-"current" feature documented in sessions-resolution.test.ts and openclaw-tools.session-status.test.ts (prefers a literal current session key in session_status, resolves a literal current sessionId in session_status) is preserved unchanged.

PR with fix + regression test filed alongside.

extent analysis

TL;DR

The session_status tool should be updated to handle the "current" session key alias for channel-plugin-driven agents by adding a final fallback in the resolution chain.

Guidance

  • The issue arises from the resolveCurrentSessionClientAlias function only returning the requester key when the client ID matches one of the specified IDs, and the literal string "current" doesn't match any gateway client ID.
  • To fix this, a final fallback should be added in session-status-tool.ts to treat "current" as the requester's own session when both the literal-current store lookup and the gateway sessions.resolve("current") find nothing matching.
  • The fallback should be positioned after the existing literal-current paths to preserve the prefer-literal-session-named-"current" feature.
  • A regression test should be added to ensure the fix works as expected.

Example

No code snippet is provided as the issue is more related to the logic and functionality of the session_status tool rather than a specific code error.

Notes

The proposed fix should be carefully reviewed to ensure it doesn't introduce any unintended behavior or conflicts with existing features.

Recommendation

Apply the proposed fix by adding a final fallback in the resolution chain to handle the "current" session key alias for channel-plugin-driven agents. This will ensure that the session_status tool works as expected for all types of clients.

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…

FAQ

Expected behavior

sessionKey="current" should resolve to the requester's own session, regardless of whether the requester is a UI client or a channel-plugin client. That's what the universally-applied tool docstring promises.

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 - ✅(Solved) Fix session_status throws "Unknown sessionKey: current" for channel-plugin agents (~4s wasted per turn) [2 pull requests, 1 comments, 2 participants]