{"record":{"id":"015313b7b0fa47ea","repo":"JuliusBrussee/caveman","slug":"field-must-be-base64-or-null","errorCode":null,"errorMessage":"${field} must be base64 or null","messagePattern":"(.+?) must be base64 or null","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":12695,"sourceCode":"}\n\nfunction mcpMarkerBytes(mcp: { command: string; args: string[] }, tool: string, configPath?: string): Buffer {\n  return Buffer.from(JSON.stringify({\n    ...(configPath ? { schema_version: 1 } : {}),\n    tool,\n    command: mcp.command,\n    args: mcp.args,\n    ...(configPath ? { config_path: canonicalMcpConfigPath(configPath) } : {}),\n  }, null, 2) + \"\\n\");\n}\n\nfunction validMcpMarkerBytes(bytes: Buffer, agent: \"kilo\" | \"qwen\", serverName: string): boolean {\n  return parseMcpServerMarkerBytes(agent, serverName, bytes) !== null;\n}\n\nfunction decodePendingBytes(value: unknown, field: string): Buffer | null {\n  if (value === null) return null;\n  if (typeof value !== \"string\") throw new Error(`${field} must be base64 or null`);\n  const bytes = Buffer.from(value, \"base64\");\n  if (bytes.toString(\"base64\") !== value) throw new Error(`${field} is not canonical base64`);\n  return bytes;\n}\n\nfunction validOptionalHash(value: unknown): value is string | null {\n  return value === null || (typeof value === \"string\" && /^sha256:[0-9a-f]{64}$/.test(value));\n}\n\ntype ReadOwnedMcpPendingJournal = {\n  journal: OwnedMcpPendingJournal;\n  configBefore: Buffer | null;\n  markerBefore: Buffer | null;\n  markerAfter: Buffer | null;\n  path: string;\n  bytes: Buffer;\n};\n","sourceCodeStart":12677,"sourceCodeEnd":12713,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L12677-L12713","documentation":"decodePendingBytes validates a field of a pending MCP transaction journal. The value must be either JSON null or a base64 string; any other JSON type (number, boolean, object, array) is rejected. This enforces the journal's schema before bytes are decoded for integrity checks.","triggerScenarios":"A hand-edited or partially written pending-transaction journal file contains a non-string, non-null value for config_before_base64, marker_before_base64, or marker_after_base64.","commonSituations":"Manually editing the journal file to repair a stuck transaction; a tool corrupting the JSON types; an older/newer schema version writing differently-typed fields.","solutions":["Restore the journal field to a valid base64 string or explicit null","Delete the pending transaction journal and re-run the MCP operation from scratch","Regenerate the journal by re-running the interrupted command instead of hand-editing"],"exampleFix":"// before\n{ \"config_before_base64\": 12345 }\n// after\n{ \"config_before_base64\": \"eyJhIjoxfQ==\" }","handlingStrategy":"type-guard","validationCode":"function isBase64OrNull(v: unknown): boolean {\n  return v === null || (typeof v === 'string' && Buffer.from(v, 'base64').toString('base64') === v);\n}","typeGuard":"function isDecodablePendingValue(v: unknown): v is string | null {\n  return v === null || typeof v === 'string';\n}","tryCatchPattern":"try {\n  decodePendingBytes(journal.config_before_base64, 'config_before_base64');\n} catch (e) {\n  if (e instanceof Error && e.message.includes('must be base64 or null')) {\n    // treat journal as invalid: discard or regenerate\n  } else throw e;\n}","preventionTips":["Never hand-edit journal base64 fields to non-string JSON types","Validate journal JSON types before writing it back","Use a schema validator on the journal after any manual modification","Regenerate journals via the CLI rather than crafting them manually"],"tags":["validation","mcp","base64","journal"],"backgroundTag":"schema-validation-failed","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}