Skip to content

fix(agents): runEmbeddedPiAgent/runEmbeddedAttempt blindly forward params.sessionKey — no backfill when omitted #60552

@100yenadmin

Description

@100yenadmin

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:

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

Environment

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions