JuliusBrussee/caveman · error · Error
pending ${label} transaction is malformed: ${(error as Error
Error message
pending ${label} transaction is malformed: ${(error as Error).message} What it means
A wrapper thrown around any error raised inside the journal validation/decoding try-block (including errors 21, 22, 24, 26, 27 from decodePendingBytes and cross-field checks). It prefixes the original message with 'pending <label> transaction is malformed:' so callers know the pending journal for that transaction label is unusable and recovery was refused.
Source
Thrown at packages/cli/src/index.ts:12422
|| optionalBytesHash(markerAfter) !== value.marker_after_sha256
|| (markerBefore !== null && !validMcpMarkerBytes(markerBefore, journalAgent, journalServer))
|| (markerAfter !== null && !validMcpMarkerBytes(markerAfter, journalAgent, journalServer))
|| (markerBefore !== null && parseMcpServerMarkerBytes(journalAgent, journalServer, markerBefore)?.config_path !== undefined
&& parseMcpServerMarkerBytes(journalAgent, journalServer, markerBefore)?.config_path !== value.config_path)
|| (markerAfter !== null && parseMcpServerMarkerBytes(journalAgent, journalServer, markerAfter)?.config_path !== value.config_path)
|| (value.action === "install") !== (markerAfter !== null)) {
throw new Error("journal bytes do not match declared transaction state");
}
return {
journal: value as OwnedMcpPendingJournal,
configBefore,
markerBefore,
markerAfter,
path,
bytes,
};
} catch (error) {
throw new Error(`pending ${label} transaction is malformed: ${(error as Error).message}`);
}
}
function readOwnedMcpPendingLocator(agent: "kilo" | "qwen", serverName: string): ReadOwnedMcpPendingJournal | null {
const path = canonicalMcpConfigPath(mcpPendingJournalPath(agent, serverName));
return readOwnedMcpPendingJournalAt(path, { agent, serverName, locatorPath: path });
}
function readOwnedMcpConfigPending(configPath: string): ReadOwnedMcpPendingJournal | null {
const canonicalPath = canonicalMcpConfigPath(configPath);
return readOwnedMcpPendingJournalAt(mcpConfigPendingJournalPath(canonicalPath), { configPath: canonicalPath });
}
type OwnedMcpRecovery = "none" | "discarded" | "finalized" | "rolled-back";
function recoverOwnedMcpTransaction(pending: ReadOwnedMcpPendingJournal | null): OwnedMcpRecovery {
if (!pending) return "none";
const { journal, configBefore, markerBefore } = pending;View on GitHub (pinned to 5184b3d11a)
Solutions
- Read the inner message after 'is malformed:' to identify the exact validation failure.
- Fix the specific field or condition named by the inner message (see the underlying errors).
- Delete the malformed .pending journals and re-run the MCP server transaction to regenerate valid ones.
- If recurring, ensure only one CLI version writes journals and avoid manual edits or third-party rewrites.
Example fix
// before (diagnosing blindly)
kilo mcp recover
// after
node -e 'const j=JSON.parse(require("fs").readFileSync("x.pending")); console.log(j)' # inspect, fix inner cause, then recover Defensive patterns
Strategy: try-catch
Try / catch
try { recoverPending(); } catch (e) {
const m = /is malformed: (.+)$/.exec(e.message);
if (m) { console.error('Inner cause:', m[1]); /* address inner cause or recreate journal */ }
} Prevention
- Parse the inner message after 'is malformed:' to target the real fix.
- Treat any malformed journal as unrecoverable: recreate it via a fresh transaction.
- Avoid hand edits and version-mixed writers of journal files.
When it happens
Trigger: Any of: non-string base64 field, non-canonical base64, non-object JSON, bad schema_version/action/mode/hash fields, or bytes-vs-state mismatch, surfaced while reading the pending journal for an MCP install/uninstall recovery.
Common situations: Same as the inner errors — corrupted or hand-edited journals, version-skewed writers, wrong server/agent pairing — seen through this outer wrapper in logs.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- recordOutcome: values must be a non-empty plain object
- recordOutcome: evidence must be a plain object
- recordOutcome: evidence keys must be non-empty
- recordOutcome: evidence.${key} must be a string, number, or
- recordOutcome: evidence.${key} must be a finite number
AI-assisted analysis of JuliusBrussee/caveman@5184b3d11a (2026-09-06).
Data as JSON: /api/errors/c1ed88c563807d45.
Report an issue: GitHub.