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
- Inspect the node-side resume logs to see why it returned ok !== true (the underlying error is usually there).
- Confirm the node's resume handler emits { ok: true, text: string, sessionId? } on success.
- Retry the resume once transient node errors are ruled out.
- 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
- Ensure the node resume handler returns { ok: true, text, sessionId? } on success and a clear error on failure.
- Version-match the invoking plugin with the node plugin's resume handler.
- Log unwrapNodeInvokePayload output at debug level to catch envelope drift.
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
- Missing or invalid Codex CLI session id.
- Missing Codex CLI prompt.
- Codex CLI session list returned an invalid payload.
- Codex CLI node command returned malformed payloadJSON.
- Codex thread/resume returned no cwd for ${normalizedThreadId
AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12).
Data as JSON: /api/errors/12a4cd47938a8b9b.
Report an issue: GitHub.