Hmbown/CodeWhale · error
invalid session id
Error message
invalid session id
What it means
write_session_archive refuses to build a session archive when the session's metadata.id is not a valid session id (checked by is_valid_session_id). Session ids become tar member names / file paths, so an invalid id could escape the archive layout or produce a corrupt archive.
Solutions
- Check the session metadata id; regenerate or repair the session record with a valid id.
- Export a different session and re-derive the broken one from its transcript.
- If constructing sessions in code, generate ids with the session store's id generator instead of raw strings.
Example fix
// before
let session = SavedSession { metadata: SessionMetadata { id: "../evil".into(), .. } };
// after
let session = SavedSession { metadata: SessionMetadata { id: SessionId::generate(), .. } }; Defensive patterns
Strategy: validation
Validate before calling
fn id_ok(id: &str) -> bool { !id.is_empty() && id.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') }
assert!(id_ok(&session.metadata.id), "invalid session id: {:?}", session.metadata.id); Type guard
fn valid_session(s: &SavedSession) -> bool { is_valid_session_id(&s.metadata.id) } Try / catch
match write_session_archive(&s, dir, out, opts) { Err(e) if e.kind() == io::ErrorKind::InvalidInput && e.to_string() == "invalid session id" => skip_and_log(&s.metadata.id), r => r?, } Prevention
- Generate session ids with the store's id generator, never arbitrary strings
- Validate ids after importing sessions from older formats
- Treat corrupt metadata as a signal to rebuild the session record
When it happens
Trigger: Calling write_session_archive (crates/tui/src/session_export.rs:147) with a SavedSession whose metadata.id contains path separators, is empty, or otherwise fails is_valid_session_id — typically a hand-constructed session record or one imported from an incompatible format.
Common situations: Exporting sessions from an older/newer store with a different id format; constructing SavedSession in tests or scripts with an arbitrary id string; corrupted session metadata file.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- {error}
- export output must be outside the session store
- invalid session id for memory reconcile
- legacy spillover ownership requires a session id
- Mobile session bootstrap was incomplete
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/ade927cf8a1048f1.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/session_export.rs:147
///
/// `session` is typically loaded with
/// [`SessionManager::load_session_snapshot`](crate::session_manager::SessionManager::load_session_snapshot)
/// so the archive reflects the durable record without applying resume-time
/// repair. `sessions_dir` is the trusted session store root; pass `None` (or clear
/// [`SessionArchiveOptions::include_artifacts`]) to export the transcript
/// only.
///
/// The archive is streamed to a sibling temporary file and renamed into
/// place, so a failed export never leaves a truncated archive at `output`.
/// An existing `output` is replaced only when `options.overwrite` is set.
pub fn write_session_archive(
session: &SavedSession,
sessions_dir: Option<&Path>,
output: &Path,
options: SessionArchiveOptions,
) -> io::Result<SessionArchiveSummary> {
if !is_valid_session_id(&session.metadata.id) {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"invalid session id",
));
}
if options.compression_level > 9 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!(
"xz compression level {} is out of range 0-9",
options.compression_level
),
));
}
let session_json = session_json(session)?;
let container_json = container_json(session)?;
let parent = output
.parent()
.filter(|parent| !parent.as_os_str().is_empty())View on GitHub (pinned to 73e0f67d83)