openclaw - ✅(Solved) Fix fix(agents): runEmbeddedPiAgent/runEmbeddedAttempt blindly forward params.sessionKey — no backfill when omitted [2 pull requests, 1 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#60552Fetched 2026-04-08 02:49:42
View on GitHub
Comments
0
Participants
1
Timeline
27
Reactions
0
Participants
Timeline (top)
referenced ×23cross-referenced ×3closed ×1

Root Cause

The correct resolver already exists in the codebase: resolveSessionKeyForRequest() from src/agents/command/session.ts. It's synchronous and store-backed — it resolves a sessionKey from sessionId when sessionKey is not provided.

The issue is that runEmbeddedPiAgent and runEmbeddedAttempt in src/agents/pi-embedded-runner/run.ts don't call it. They just pass through whatever params.sessionKey they receive.

Fix Action

Fix / Workaround

  • Downstream impact: Martian-Engineering/lossless-claw#176 (ignoreSessionPatterns no-ops on null session_key)
  • Partial fix: #49052 (threads sessionKey to extension factories, but doesn't resolve it when missing)
  • We have a working source-level patch with regression test at 100yenadmin/eva-core — happy to upstream as a PR if wanted

PR fix notes

PR #60555: fix(agents): backfill missing sessionKey in embedded PI runner — prevents undefined key in model selection and live-switch

Description (problem / solution / changelog)

What this fixes (plain English)

When a chat session was started with only a session ID (no session key), downstream features like hooks, live-model switching, and error formatting would break because they expected a session key. This fix resolves the session key from the store at startup, so all downstream paths work correctly.

Technical details

Root cause: The embedded runner could receive a sessionId without a corresponding sessionKey. Downstream paths (hooks, live-model switch, error formatting, pending-clear) all require sessionKey but received undefined.

Fix: Added resolveSessionKeyForRequest() backfill at the start of the embedded runner when only sessionId is provided. The resolved key is used consistently throughout the run lifecycle. Logs a warning if backfill resolution fails (instead of silently swallowing).

Files changed:

  • src/agents/pi-embedded-runner/run.ts — backfill sessionKey from sessionId via resolver
  • src/agents/command/session.ts — updated docstring
  • src/agents/pi-embedded-runner.e2e.test.ts — e2e regression test for sessionKey backfill
  • src/gateway/sessions-history-http.test.ts — SSE seq validation: verifies NO_REPLY messages are excluded from streamed history and seq numbering is correct
  • CHANGELOG.md — release note for the sessionKey backfill fix

Related

  • Fixes #60552
  • Related: #29203 (hooks missing sessionKey), #52390 (missing sessionKey in message hook path), #58083 (cron jobs persisting wrong sessionKey)

Test plan

  • 60/60 tests pass (model + tool-result-context-guard suites)
  • Regression test: successful sessionId -> sessionKey backfill
  • Regression test: warning log emission when backfill resolution throws
  • SSE seq validation test for NO_REPLY message filtering in session history

Changed files

  • CHANGELOG.md (modified, +1/-1)
  • src/agents/command/session.resolve-session-key.test.ts (modified, +30/-1)
  • src/agents/command/session.ts (modified, +35/-3)
  • src/agents/pi-embedded-runner.e2e.test.ts (modified, +188/-1)
  • src/agents/pi-embedded-runner/run.ts (modified, +63/-6)
  • src/gateway/sessions-history-http.test.ts (modified, +20/-4)

PR #60562: fix(models): correct gpt-5.4 context window to 1_050_000 in provider constants

Description (problem / solution / changelog)

Fixes #42225. See issue for full context.

PR #37876 only fixed the forward-compat path in model-forward-compat.ts, but that path is unreachable when gpt-5.4 already exists in the Pi SDK catalog (the common case). The provider-level constants in both openai-codex-provider.ts and openai-provider.ts still had the stale 272_000 value.

Fix: Two one-line constant changes: 272_000 → 1_050_000 in both providers.

Note: gpt-5.4-pro already correctly had 1_050_000 in openai-provider.ts — this brings base gpt-5.4 in line.

Config-only workaround (for immediate relief without this PR): add contextWindow: 1050000 under models.providers.openai-codex.models.gpt-5.4 in openclaw.json.

Changed files

  • extensions/openai/openai-codex-provider.ts (modified, +1/-1)
  • extensions/openai/openai-provider.ts (modified, +1/-1)
  • src/agents/pi-embedded-runner/run.ts (modified, +42/-0)

Code Example

SELECT COUNT(*) FROM conversations WHERE session_key IS NULL;
-- Result: 847 conversations with null session_key

---

import { resolveSessionKeyForRequest } from '../command/session.js';

function backfillSessionKey(params: { sessionId: string; sessionKey?: string }): string | undefined {
  if (params.sessionKey) return params.sessionKey;
  return resolveSessionKeyForRequest({ sessionId: params.sessionId });
}
RAW_BUFFERClick to expand / collapse

Problem

runEmbeddedPiAgent() and runEmbeddedAttempt() forward params.sessionKey directly to downstream consumers (hooks, compaction, LCM ingest). When callers omit sessionKey (which at least 2 confirmed call sites do), it propagates as undefined/null through:

  • Hook contexts (beforeAgentStart, afterAgentEnd, beforeCompaction)
  • LCM/lossless-claw afterTurn() → stored as session_key = NULL in the LCM database
  • Compaction flows

Evidence from production

We found thousands of LCM database rows with session_key = NULL:

SELECT COUNT(*) FROM conversations WHERE session_key IS NULL;
-- Result: 847 conversations with null session_key

These null-key conversations break downstream features including:

  • ignoreSessionPatterns glob matching silently no-ops (Martian-Engineering/lossless-claw#176)
  • Session-scoped compaction routing
  • Any extension that uses sessionKey for session identification

Root cause

The correct resolver already exists in the codebase: resolveSessionKeyForRequest() from src/agents/command/session.ts. It's synchronous and store-backed — it resolves a sessionKey from sessionId when sessionKey is not provided.

The issue is that runEmbeddedPiAgent and runEmbeddedAttempt in src/agents/pi-embedded-runner/run.ts don't call it. They just pass through whatever params.sessionKey they receive.

Proposed fix

Add a backfill step at the top of the runner boundary (run.ts) that resolves sessionKey from sessionId when sessionKey is not explicitly provided:

import { resolveSessionKeyForRequest } from '../command/session.js';

function backfillSessionKey(params: { sessionId: string; sessionKey?: string }): string | undefined {
  if (params.sessionKey) return params.sessionKey;
  return resolveSessionKeyForRequest({ sessionId: params.sessionId });
}

Then use the resolved key for all downstream consumers. Explicit sessionKey takes precedence (no behavior change for callers that already provide it).

Related

  • Downstream impact: Martian-Engineering/lossless-claw#176 (ignoreSessionPatterns no-ops on null session_key)
  • Partial fix: #49052 (threads sessionKey to extension factories, but doesn't resolve it when missing)
  • We have a working source-level patch with regression test at 100yenadmin/eva-core — happy to upstream as a PR if wanted

Environment

  • OpenClaw v2026.4.2
  • Affects: src/agents/pi-embedded-runner/run.tsrunEmbeddedPiAgent(), runEmbeddedAttempt()

extent analysis

TL;DR

Add a backfill step to resolve the sessionKey from sessionId when it's not explicitly provided in runEmbeddedPiAgent and runEmbeddedAttempt functions.

Guidance

  • Identify the callers of runEmbeddedPiAgent and runEmbeddedAttempt that omit the sessionKey parameter to ensure they are handled correctly after the fix.
  • Use the proposed backfillSessionKey function to resolve the sessionKey from sessionId when it's not provided, and use the resolved key for all downstream consumers.
  • Verify that the fix works by checking the LCM database for session_key = NULL rows and ensuring that downstream features like ignoreSessionPatterns glob matching and session-scoped compaction routing work as expected.
  • Consider upstreaming the working source-level patch with regression test from 100yenadmin/eva-core to fix the issue permanently.

Example

function runEmbeddedPiAgent(params: { sessionId: string; sessionKey?: string }) {
  const sessionKey = backfillSessionKey(params);
  // Use the resolved sessionKey for downstream consumers
}

Notes

The proposed fix assumes that the resolveSessionKeyForRequest function is correctly implemented and works as expected. Additionally, the fix only addresses the issue in runEmbeddedPiAgent and runEmbeddedAttempt functions and may not cover other potential callers that omit the sessionKey parameter.

Recommendation

Apply the proposed workaround by adding the backfillSessionKey function and using it to resolve the sessionKey from sessionId when it's not provided. This will ensure that downstream consumers receive a valid sessionKey and prevent issues like null sessionKey in the LCM database.

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