Hmbown/CodeWhale · error · io::Error
legacy spillover ownership requires a session id
Error message
legacy spillover ownership requires a session id
What it means
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.
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.
Example fix
// before
publish_legacy_spillover_ownership(&payload, "", &bytes)? // empty session id
// after
let sid = context.session_id.as_deref().unwrap_or_else(|| panic!("session id required"));
publish_legacy_spillover_ownership(&payload, sid, &bytes)? Defensive patterns
Strategy: validation
Validate before calling
// guard before invoking the spillover path
if session_id.trim().is_empty() { return Err("spillover requires an initialized session id"); } Type guard
fn has_session_id(id: &str) -> bool { !id.trim().is_empty() } Try / catch
// rust
match apply_spillover(...) {
Err(e) if e.to_string().contains("requires a session id") => {
eprintln!("session not initialized; create a session before spillover");
}
other => other?,
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- agent profile cannot be empty
- BYDAY cannot be empty for WEEKLY schedules
- continual harness entry id cannot be empty
- custom provider base URL is required
- custom provider name is required
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/308d2aab34f522bf.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/truncate.rs:140
}
#[must_use]
pub(crate) fn legacy_spillover_ownership_path(payload_path: &Path) -> PathBuf {
payload_path.with_extension("owner.json")
}
/// Publish the proof needed to retrieve a legacy-global spillover safely.
///
/// Payload publication happens first. If this atomic sidecar write fails, the
/// payload is deliberately left unowned and therefore inaccessible through
/// `retrieve_tool_result`; callers must not advertise a retrieval hint.
pub(crate) fn publish_legacy_spillover_ownership(
payload_path: &Path,
session_id: &str,
bytes: &[u8],
) -> io::Result<PathBuf> {
if session_id.trim().is_empty() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"legacy spillover ownership requires a session id",
));
}
let ownership = LegacySpilloverOwnership {
schema_version: LEGACY_SPILLOVER_OWNER_SCHEMA_VERSION,
origin_session: session_id.to_string(),
digest: crate::hashing::sha256_hex(bytes),
size_bytes: bytes.len().try_into().unwrap_or(u64::MAX),
};
let sidecar = legacy_spillover_ownership_path(payload_path);
let encoded = serde_json::to_vec_pretty(&ownership)
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
crate::utils::write_atomic(&sidecar, &encoded)?;
Ok(sidecar)
}
pub(crate) fn read_legacy_spillover_ownership(View on GitHub (pinned to 73e0f67d83)