{"record":{"id":"308d2aab34f522bf","repo":"Hmbown/CodeWhale","slug":"legacy-spillover-ownership-requires-a-session-id","errorCode":null,"errorMessage":"legacy spillover ownership requires a session id","messagePattern":"legacy spillover ownership requires a session id","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tools/truncate.rs","lineNumber":140,"sourceCode":"}\n\n#[must_use]\npub(crate) fn legacy_spillover_ownership_path(payload_path: &Path) -> PathBuf {\n    payload_path.with_extension(\"owner.json\")\n}\n\n/// Publish the proof needed to retrieve a legacy-global spillover safely.\n///\n/// Payload publication happens first. If this atomic sidecar write fails, the\n/// payload is deliberately left unowned and therefore inaccessible through\n/// `retrieve_tool_result`; callers must not advertise a retrieval hint.\npub(crate) fn publish_legacy_spillover_ownership(\n    payload_path: &Path,\n    session_id: &str,\n    bytes: &[u8],\n) -> io::Result<PathBuf> {\n    if session_id.trim().is_empty() {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            \"legacy spillover ownership requires a session id\",\n        ));\n    }\n    let ownership = LegacySpilloverOwnership {\n        schema_version: LEGACY_SPILLOVER_OWNER_SCHEMA_VERSION,\n        origin_session: session_id.to_string(),\n        digest: crate::hashing::sha256_hex(bytes),\n        size_bytes: bytes.len().try_into().unwrap_or(u64::MAX),\n    };\n    let sidecar = legacy_spillover_ownership_path(payload_path);\n    let encoded = serde_json::to_vec_pretty(&ownership)\n        .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;\n    crate::utils::write_atomic(&sidecar, &encoded)?;\n    Ok(sidecar)\n}\n\npub(crate) fn read_legacy_spillover_ownership(","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tools/truncate.rs#L122-L158","documentation":"publish_legacy_spillover_ownership writes a sidecar that records which session owns a legacy spillover payload. It refuses to proceed when the session id is empty or whitespace-only, returning InvalidInput with this message, because an owner-less ownership record would be meaningless and unresolvable later.","triggerScenarios":"apply_spillover_inner calling publish_legacy_spillover_ownership with a session_id that is \"\" or contains only whitespace — typically when the session context was not initialized or the id was not propagated to the truncate/spillover path.","commonSituations":"Running a tool invocation outside a proper session (early startup, tests with a stub context); a session id field defaulted to empty string; regression in session-id plumbing after refactor.","solutions":["Ensure the session is initialized before triggering spillover so a real session id reaches apply_spillover_inner.","Check where session_id originates (context/session manager) and fix the code path that yields an empty value.","In tests or scripts, pass an explicit non-empty session id instead of \"\".","Add an early guard that fails loud at session creation if the generated id is empty."],"exampleFix":"// before\npublish_legacy_spillover_ownership(&payload, \"\", &bytes)?  // empty session id\n// after\nlet sid = context.session_id.as_deref().unwrap_or_else(|| panic!(\"session id required\"));\npublish_legacy_spillover_ownership(&payload, sid, &bytes)?","handlingStrategy":"validation","validationCode":"// guard before invoking the spillover path\nif session_id.trim().is_empty() { return Err(\"spillover requires an initialized session id\"); }","typeGuard":"fn has_session_id(id: &str) -> bool { !id.trim().is_empty() }","tryCatchPattern":"// rust\nmatch apply_spillover(...) {\n    Err(e) if e.to_string().contains(\"requires a session id\") => {\n        eprintln!(\"session not initialized; create a session before spillover\");\n    }\n    other => other?,\n}","preventionTips":["Initialize the session before any tool path that can spill over.","Never default session ids to empty string; generate a real id or fail at creation.","Assert non-empty session id in test fixtures that exercise spillover."],"tags":["validation","session","spillover","empty-value"],"backgroundTag":"empty-required-field","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}