{"record":{"id":"2967314db6050645","repo":"Hmbown/CodeWhale","slug":"xz-compression-level-is-out-of-range-0-9","errorCode":null,"errorMessage":"xz compression level {} is out of range 0-9","messagePattern":"xz compression level (.+?) is out of range 0-9","errorType":"validation","errorClass":"io::Error (InvalidInput)","httpStatus":null,"severity":"error","filePath":"crates/tui/src/session_export.rs","lineNumber":153,"sourceCode":"/// only.\n///\n/// The archive is streamed to a sibling temporary file and renamed into\n/// place, so a failed export never leaves a truncated archive at `output`.\n/// An existing `output` is replaced only when `options.overwrite` is set.\npub fn write_session_archive(\n    session: &SavedSession,\n    sessions_dir: Option<&Path>,\n    output: &Path,\n    options: SessionArchiveOptions,\n) -> io::Result<SessionArchiveSummary> {\n    if !is_valid_session_id(&session.metadata.id) {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            \"invalid session id\",\n        ));\n    }\n    if options.compression_level > 9 {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            format!(\n                \"xz compression level {} is out of range 0-9\",\n                options.compression_level\n            ),\n        ));\n    }\n    let session_json = session_json(session)?;\n    let container_json = container_json(session)?;\n    let parent = output\n        .parent()\n        .filter(|parent| !parent.as_os_str().is_empty())\n        .map_or_else(|| PathBuf::from(\".\"), Path::to_path_buf);\n    fs::create_dir_all(&parent)?;\n    let sessions_dir = sessions_dir.map(Path::canonicalize).transpose()?;\n    if let Some(root) = &sessions_dir\n        && parent.canonicalize()?.starts_with(root)\n    {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/session_export.rs#L135-L171","documentation":"write_session_archive only accepts xz compression levels 0 through 9. Passing `SessionArchiveOptions.compression_level` greater than 9 is rejected up front with InvalidInput, since the underlying xz encoder does not support it. The error message includes the offending level value.","triggerScenarios":"Calling `write_session_archive` with `options.compression_level = 10` or higher (or a value computed/parsed from user input without clamping).","commonSituations":"A CLI flag parsed with the wrong type or bounds; a config file where the level was set for a different library (e.g. gzip-style 0-12 or zstd levels); arithmetic producing an off-by-one level.","solutions":["Clamp the level to 0..=9 before calling: `options.compression_level = options.compression_level.min(9)`.","Fix the CLI/config parsing to enforce the 0-9 range (e.g. `value_range(0..=9)` or a `clap` value parser).","Use level 9 for maximum compression, or 6 as the typical xz default.","Check the source of the value — if it comes from another tool's preset, map it into xz's range."],"exampleFix":"// before\nlet options = SessionArchiveOptions { compression_level: 12, ..opts };\nwrite_session_archive(&session, dir, out, options)?;\n// after\nlet options = SessionArchiveOptions { compression_level: opts.compression_level.clamp(0, 9), ..opts };\nwrite_session_archive(&session, dir, out, options)?;","handlingStrategy":"validation","validationCode":"fn valid_compression_level(level: i32) -> bool { (0..=9).contains(&level) }\n// call before: assert!(valid_compression_level(options.compression_level));","typeGuard":"fn in_xz_range(level: i32) -> Option<u32> { u32::try_from(level).ok().filter(|l| *l <= 9) }","tryCatchPattern":"match write_session_archive(&session, dir, out, opts) {\n    Err(e) if e.to_string().contains(\"out of range 0-9\") => {\n        let mut opts = opts; opts.compression_level = 6;\n        write_session_archive(&session, dir, out, opts)?;\n    }\n    other => other?,\n}","preventionTips":["Parse the level with a 0..=9 value parser at the CLI boundary","Don't reuse level presets from gzip/zstd; map them into xz's range","Default to level 6 (xz default) unless the user opts into more"],"tags":["validation","compression","cli","session-export"],"backgroundTag":"value-out-of-range","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"}