Hmbown/CodeWhale · error
export output must be outside the session store
Error message
export output must be outside the session store
What it means
Before writing the archive, the function canonicalizes the output's parent directory and the sessions store root, and refuses output paths that resolve inside the session store. Writing a tarball into the store could be re-ingested as session data or grow on every export.
Solutions
- Choose an output path outside the sessions directory (e.g. ~/exports/session.tar.xz).
- If exporting from within the store dir, pass an explicit --output elsewhere.
- Resolve symlinks: point the output at a real directory that is not under the store root.
Example fix
// before cd ~/.codewhale/sessions && codewhale sessions export --output ./backup.tar.xz // after codewhale sessions export --output ~/backups/session.tar.xz
Defensive patterns
Strategy: validation
Validate before calling
let root = sessions_dir.canonicalize()?;
let parent = output.parent().unwrap_or(Path::new(".")).canonicalize()?;
assert!(!parent.starts_with(&root), "output must be outside the session store"); Try / catch
match write_session_archive(&s, Some(&store), &out, o) { Err(e) if e.to_string().contains("outside the session store") => eprintln!("move --output outside {}", store.display()), r => r?, } Prevention
- Default export output to a directory outside the sessions store
- Resolve symlinks before choosing the output directory
- Reject store-resolving output paths in CLI arg parsing with a clear message
When it happens
Trigger: Calling write_session_archive (crates/tui/src/session_export.rs:172) with an output path whose canonicalized parent is equal to or nested under the canonicalized sessions_dir (including via symlink).
Common situations: Exporting with output defaulting to the current directory while cwd is the sessions directory; symlinked output directory resolving into the store; scripts writing backups next to session data.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- {error}
- invalid session id
- already exists; pass --force to overwrite it
- Ambiguous prefix ' ' matches sessions
- artifact id and extension must contain safe ASCII characters
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/b8b1231a14f697fc.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/session_export.rs:172
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())
.map_or_else(|| PathBuf::from("."), Path::to_path_buf);
fs::create_dir_all(&parent)?;
let sessions_dir = sessions_dir.map(Path::canonicalize).transpose()?;
if let Some(root) = &sessions_dir
&& parent.canonicalize()?.starts_with(root)
{
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"export output must be outside the session store",
));
}
let artifact_files = match (options.include_artifacts, sessions_dir.as_deref()) {
(true, Some(root)) => match session_artifacts_dir(root, &session.metadata.id)? {
Some(dir) => collect_artifact_files(root, &dir)?,
None => Vec::new(),
},
_ => Vec::new(),
};
let mut temp = tempfile::Builder::new()
.prefix(".codewhale-session-export-")
.tempfile_in(&parent)?;
let mut summary = SessionArchiveSummary {
output: output.to_path_buf(),
session_id: session.metadata.id.clone(),View on GitHub (pinned to 73e0f67d83)