openclaw/openclaw · error

Codex CLI resume returned an invalid payload.

Error message

Codex CLI resume returned an invalid payload.

What it means

The resumeCodexCliSessionOnNode node invoke returned a payload that is not a record, or whose ok !== true, or whose text is not a string. resumeCodexCliSessionOnNode unwraps the node invoke result and requires a success envelope { ok: true, text: string, sessionId? }; any deviation is treated as a malformed remote response.

Source

Thrown at extensions/codex/src/node-cli-sessions.ts:172

  prompt: string;
  cwd?: string;
  timeoutMs?: number;
}): Promise<CodexCliSessionResumeResult> {
  const raw = await params.runtime.nodes.invoke({
    nodeId: params.nodeId,
    command: CODEX_CLI_SESSION_RESUME_COMMAND,
    params: {
      sessionId: params.sessionId,
      prompt: params.prompt,
      cwd: params.cwd,
      timeoutMs: params.timeoutMs,
    },
    timeoutMs: (params.timeoutMs ?? DEFAULT_RESUME_TIMEOUT_MS) + 5_000,
    scopes: ["operator.write"],
  });
  const payload = unwrapNodeInvokePayload(raw);
  if (!isRecord(payload) || payload.ok !== true || typeof payload.text !== "string") {
    throw new Error("Codex CLI resume returned an invalid payload.");
  }
  return {
    ok: true,
    sessionId: typeof payload.sessionId === "string" ? payload.sessionId : params.sessionId,
    text: payload.text,
  };
}

export function formatCodexCliSessions(params: {
  node: CodexCliSessionNodeInfo;
  result: CodexCliSessionsListResult;
}): string {
  if (params.result.sessions.length === 0) {
    return `No Codex CLI sessions returned from ${formatCodexDisplayText(formatNodeLabel(params.node))}.`;
  }
  return [
    `Codex CLI sessions on ${formatCodexDisplayText(formatNodeLabel(params.node))}:`,
    ...params.result.sessions.map((session) => {

View on GitHub (pinned to 01804a7531)

Solutions

  1. Inspect the node-side resume logs to see why it returned ok !== true (the underlying error is usually there).
  2. Confirm the node's resume handler emits { ok: true, text: string, sessionId? } on success.
  3. Retry the resume once transient node errors are ruled out.
  4. Update the node plugin so the resume handler returns the contract envelope.
Defensive patterns

Strategy: type-guard

Type guard

function isValidResumePayload(p: unknown): p is { ok: true; text: string; sessionId?: string } {
  return typeof p === 'object' && p !== null && (p as any).ok === true && typeof (p as any).text === 'string';
}

Try / catch

try {
  const raw = await runtime.nodes.invoke({ ... });
  const payload = unwrapNodeInvokePayload(raw);
  if (!isValidResumePayload(payload)) throw new Error('invalid resume payload');
} catch (e) {
  // inspect node-side resume logs for the real ok:false cause
  throw e;
}

Prevention

When it happens

Trigger: The remote node's resume handler returned an error object { ok: false, error }, a non-object, or a success object missing the text field. unwrapNodeInvokePayload + the record/ok/text guards at node-cli-sessions.ts:172 reject it.

Common situations: The remote codex exec resume failed and the node reported ok:false; a node-side serialization bug dropped the text field; version mismatch between the invoking plugin and the node's resume handler.

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/12a4cd47938a8b9b. Report an issue: GitHub.