{"record":{"id":"bbe41f3500d12388","repo":"Hmbown/CodeWhale","slug":"evidence-metadata-exceeds-limit","errorCode":null,"errorMessage":"evidence metadata exceeds limit","messagePattern":"evidence metadata exceeds limit","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/large_output_router.rs","lineNumber":327,"sourceCode":"pub fn read_evidence_metadata(session_id: &str, handle: &str) -> io::Result<EvidenceArtifact> {\n    let relative = evidence_metadata_relative_path(handle);\n    let file = crate::artifacts::open_session_relative(session_id, &relative, false)?;\n    read_evidence_metadata_file(&file)\n}\n\n/// Bounded, no-follow read shared by publication/replay and authenticated HTTP\n/// retrieval. The caller chooses the existing session-root authority.\npub(crate) fn read_evidence_metadata_file(\n    file: &crate::fleet::files::WorkspaceFile,\n) -> io::Result<EvidenceArtifact> {\n    use std::io::Read;\n    const MAX_MANIFEST_BYTES: u64 = 64 * 1024;\n    let mut raw = Vec::new();\n    file.open_file()?\n        .take(MAX_MANIFEST_BYTES + 1)\n        .read_to_end(&mut raw)?;\n    if raw.len() as u64 > MAX_MANIFEST_BYTES {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            \"evidence metadata exceeds limit\",\n        ));\n    }\n    serde_json::from_slice(&raw).map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))\n}\n\n#[must_use]\npub fn unix_millis_now() -> u64 {\n    std::time::SystemTime::now()\n        .duration_since(std::time::UNIX_EPOCH)\n        .unwrap_or_default()\n        .as_millis()\n        .try_into()\n        .unwrap_or(u64::MAX)\n}\n\n#[must_use]","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/large_output_router.rs#L309-L345","documentation":"read_evidence_metadata_file reads the evidence metadata sidecar capped at MAX_MANIFEST_BYTES (64 KiB) via Read::take. If the file exceeds that cap the read is truncated and the function returns InvalidData with \"evidence metadata exceeds limit\" instead of parsing a partial document. This guards the session log and memory against oversized or corrupted manifests.","triggerScenarios":"read_evidence_metadata -> read_evidence_metadata_file encountering a metadata sidecar larger than 64 KiB — typically a file corrupted by a past bug, appended garbage, or an artifact schema that grew past the limit.","commonSituations":"A previous version wrote unbounded metadata; concurrent writes produced a bloated/partial file; a hand-edited or externally modified sidecar; many large entries accumulated in one artifact.","solutions":["Delete or regenerate the oversized sidecar (remove the evidence metadata file next to the artifact) so it is rewritten on next publish.","Inspect the file (`ls -l`, `wc -c`) to confirm it is bloated/corrupt before deleting.","If legitimate metadata now exceeds 64 KiB, raise MAX_MANIFEST_BYTES or split the artifact into multiple metadata files.","Fix any writer that appends instead of atomically replacing the sidecar."],"exampleFix":"// before\nls -l ~/.local/state/codewhale/artifacts/<sid>/evidence/meta.json  # 210000 bytes\n// after\nrm ~/.local/state/codewhale/artifacts/<sid>/evidence/meta.json  # regenerated on next publish_evidence_metadata","handlingStrategy":"validation","validationCode":"// shell check before read\n[ \"$(stat -c%s \"$SIDECAR\")\" -le 65536 ] || echo \"sidecar too large; regenerate it\"","typeGuard":null,"tryCatchPattern":"// rust\nmatch read_evidence_metadata(&handle) {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains(\"exceeds limit\") => {\n        eprintln!(\"metadata sidecar over 64 KiB; delete and regenerate\");\n    }\n    other => other?,\n}","preventionTips":["Treat the 64 KiB cap as a schema budget; split large artifacts into multiple metadata files.","Always write sidecars atomically (write_atomic) so size and content stay consistent.","Monitor sidecar sizes in tests; alert before growth crosses the cap."],"tags":["file-size","limit","artifacts","validation"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}