{"record":{"id":"384b6ea946a2a1f1","repo":"nikivdev/code","slug":"archive-message-cannot-be-empty","errorCode":null,"errorMessage":"archive message cannot be empty","messagePattern":"archive message cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/archive.rs","lineNumber":22,"sourceCode":"use anyhow::{Context, Result, bail};\nuse chrono::Local;\n\nuse crate::ai_context;\nuse crate::cli::ArchiveOpts;\n\npub fn run(opts: ArchiveOpts) -> Result<()> {\n    let root =\n        ai_context::find_project_root().ok_or_else(|| anyhow::anyhow!(\"project root not found\"))?;\n    let root = fs::canonicalize(&root).unwrap_or(root);\n    let project_name = root\n        .file_name()\n        .and_then(|name| name.to_str())\n        .filter(|name| !name.trim().is_empty())\n        .unwrap_or(\"project\");\n\n    let message = opts.message.trim();\n    if message.is_empty() {\n        bail!(\"archive message cannot be empty\");\n    }\n    let slug = sanitize_segment(message);\n    if slug.is_empty() {\n        bail!(\"archive message must include at least one letter or number\");\n    }\n\n    let home = dirs::home_dir()\n        .ok_or_else(|| anyhow::anyhow!(\"could not resolve home directory\"))?\n        .to_path_buf();\n    let archive_root = home.join(\"archive\").join(\"code\");\n    fs::create_dir_all(&archive_root).with_context(|| {\n        format!(\n            \"failed to create archive directory {}\",\n            archive_root.display()\n        )\n    })?;\n\n    let code_root = fs::canonicalize(home.join(\"code\")).unwrap_or_else(|_| home.join(\"code\"));","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/archive.rs#L4-L40","documentation":"Thrown by archive.rs run when the user-supplied archive message trims to an empty string. The message doubles as the archive's slug/name, so an empty one is invalid before any filesystem work starts.","triggerScenarios":"Invoking the archive command with --message \"\" or only whitespace (e.g. `--message \"   \"`).","commonSituations":"Scripting the archive command with an empty shell variable (`--message \"$MSG\"` when MSG is unset); forgetting the message flag when it has no default.","solutions":["Pass a non-empty message: `--message \"my archive note\"`","If scripted, guard the variable before calling, e.g. require MSG to be non-empty","Omit the flag if the tool supports falling back to the default name 'project' — but note an all-whitespace value still fails"],"exampleFix":"// before\narchive --message \"$MSG\"   # MSG is empty\n// after\narchive --message \"${MSG:-snapshot}\"   # ensure a non-empty default","handlingStrategy":"validation","validationCode":"let msg = opts.message.trim();\nif msg.is_empty() {\n    return Err(\"archive message cannot be empty\".into());\n}","typeGuard":null,"tryCatchPattern":"match archive::run(opts) {\n    Err(e) if e.to_string().contains(\"message cannot be empty\") => {\n        eprintln!(\"Provide a non-empty --message.\");\n        std::process::exit(2);\n    }\n    other => other,\n}","preventionTips":["Validate the message flag in shell scripts before invoking (e.g. : \"${MSG:?empty}\")","Never interpolate possibly-empty variables into --message","Give the message a sensible default in wrappers"],"tags":["validation","argument-error","cli"],"backgroundTag":"empty-required-argument","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}