{"record":{"id":"9e9e453489301ed7","repo":"Hmbown/CodeWhale","slug":"memory-note-exceeds-max-note-bytes-bytes","errorCode":null,"errorMessage":"memory note exceeds {MAX_NOTE_BYTES} bytes","messagePattern":"memory note exceeds (.+?) bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/native_memory.rs","lineNumber":891,"sourceCode":"/// as a note. An unexplained rewrite of durable context is the thing the\n/// journal exists to prevent.\nfn normalize_evidence(evidence: &str) -> Result<String> {\n    normalize_note(evidence).map_err(|_| anyhow!(\"memory edits require non-empty evidence\"))\n}\n\nfn normalize_note(note: &str) -> Result<String> {\n    let note = note.replace(\"\\r\\n\", \"\\n\").replace('\\r', \"\\n\");\n    let note = note\n        .lines()\n        .map(str::trim)\n        .filter(|line| !line.is_empty())\n        .collect::<Vec<_>>()\n        .join(\" \");\n    if note.is_empty() {\n        bail!(\"memory note is empty\");\n    }\n    if note.len() > MAX_NOTE_BYTES {\n        bail!(\"memory note exceeds {MAX_NOTE_BYTES} bytes\");\n    }\n    Ok(note.trim_start_matches('-').trim().to_string())\n}\n\nfn validate_query(query: &str) -> Result<&str> {\n    let query = query.trim();\n    if query.is_empty() || query.chars().count() > MAX_QUERY_CHARS {\n        bail!(\"memory search query is empty or too long\");\n    }\n    Ok(query)\n}\n\nfn safe_component(value: &str) -> Result<String> {\n    if value.is_empty()\n        || value == \".\"\n        || value == \"..\"\n        || value.contains('/')\n        || value.contains('\\\\')","sourceCodeStart":873,"sourceCodeEnd":909,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/native_memory.rs#L873-L909","documentation":"`normalize_note` enforces a hard size cap (`MAX_NOTE_BYTES`) on memory notes, measured after whitespace collapsing. Oversized notes are rejected instead of silently truncating, preserving data-integrity of the memory store.","triggerScenarios":"Calling `remember`, `revise`, or `retire` with note text whose byte length (post-normalization) exceeds `MAX_NOTE_BYTES` — e.g. pasting an entire log file or a large document as a memory note.","commonSituations":"An agent dumps large tool output into memory; a user pastes a long document; a loop repeatedly appends content to one note until it blows past the cap; multi-byte UTF-8 inflates byte length beyond the character count expectation.","solutions":["Summarize or extract only the salient facts before storing.","Split the content into multiple smaller notes.","Store large content in a file and keep a short pointer/summary as the note.","Measure `note.len()` (bytes) against the cap before calling, accounting for UTF-8 multi-byte characters."],"exampleFix":"// before: dumping whole file as a note\nlet note = std::fs::read_to_string(\"big.log\")?;\nstore.remember(&note).await?;\n// after: store a summary under the cap\nlet note = summarize(&std::fs::read_to_string(\"big.log\")?);\nassert!(note.len() <= MAX_NOTE_BYTES);\nstore.remember(&note).await?;","handlingStrategy":"validation","validationCode":"// Enforce the byte cap before calling (note: bytes, not chars)\nconst MAX_NOTE_BYTES: usize = 2048; // match library constant\nif note.len() > MAX_NOTE_BYTES {\n    note = summarize(&note); // or split into multiple notes\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Summarize large content before storing; keep raw data in files with a pointer note.","Remember .len() counts bytes — multi-byte UTF-8 counts more than characters.","Split long content into several focused notes instead of one blob."],"tags":["memory","validation","size-limit"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}