{"record":{"id":"f0d0a3a6d463318a","repo":"astrid-runtime/astrid","slug":"retain-entries-must-be-at-least-1","errorCode":null,"errorMessage":"--retain-entries must be at least 1","messagePattern":"--retain-entries must be at least 1","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/audit.rs","lineNumber":107,"sourceCode":"        other => bail!(\"unexpected response from kernel: {other:?}\"),\n    };\n    let degraded = stats.degraded || health.degraded;\n    let format = ValueFormat::parse(&args.format);\n    if format.is_pretty() {\n        print_stats_pretty(&stats, &health);\n    } else {\n        emit_structured(&AuditStatsOutput { stats, health }, format)?;\n    }\n    Ok(if degraded {\n        ExitCode::from(2)\n    } else {\n        ExitCode::SUCCESS\n    })\n}\n\nasync fn run_prune(args: &AuditPruneArgs) -> Result<ExitCode> {\n    if args.retain_entries == 0 {\n        bail!(\"--retain-entries must be at least 1\");\n    }\n    if args.retain_bytes == Some(0) {\n        bail!(\"--retain-bytes must be greater than 0\");\n    }\n    let mut client = connect_as_active_agent().await?;\n    let body = into_result(\n        client\n            .request(AdminRequestKind::AuditPrune {\n                retain_entries: args.retain_entries,\n                retain_bytes: args.retain_bytes,\n            })\n            .await?,\n    )?;\n    let AdminResponseBody::AuditPruned(result) = body else {\n        bail!(\"unexpected response from kernel: {body:?}\");\n    };\n    let format = ValueFormat::parse(&args.format);\n    if format.is_pretty() {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/audit.rs#L89-L125","documentation":"In `run_prune` (crates/astrid-cli/src/commands/audit.rs:107), the CLI validates that `--retain-entries` is at least 1 before sending the AuditPrune request; passing 0 is rejected with bail!. Retaining zero entries would delete the entire audit log, so the CLI forbids it as an argument guard.","triggerScenarios":"Running `astrid-cli audit prune --retain-entries 0` (or a value that parses to 0) from a script or shell where the count was computed as 0 (e.g. empty variable, failed wc -l).","commonSituations":"Automation passing a computed retention count that evaluates to 0; typos like `--retain-entries=0`; intent to fully wipe the log, which this command intentionally disallows.","solutions":["Pass --retain-entries with a value >= 1","If the value comes from a variable/script, clamp it: RETAIN=$(( RETAIN < 1 ? 1 : RETAIN ))","If the goal is to delete everything, use the appropriate purge/wipe command instead of prune"],"exampleFix":"// before\nretain_entries=0  # or computed as 0\nastrid audit prune --retain-entries \"$retain_entries\"\n// after\nretain_entries=$(( ${retain_entries:-1} < 1 ? 1 : ${retain_entries:-1} ))\nastrid audit prune --retain-entries \"$retain_entries\"","handlingStrategy":"validation","validationCode":"#!/usr/bin/env bash\nretain=${RETAIN_ENTRIES:-1}\nif [ \"$retain\" -lt 1 ]; then\n  echo \"--retain-entries must be at least 1\" >&2; exit 64\nfi\nastrid audit prune --retain-entries \"$retain\"","typeGuard":null,"tryCatchPattern":"match astrid::commands::audit::run_prune(&args).await {\n    Ok(code) => code,\n    Err(e) if e.to_string().contains(\"--retain-entries\") => {\n        eprintln!(\"invalid retention: {e:#}\");\n        ExitCode::from(64)\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Clamp computed retention counts to >= 1 in automation before invoking the CLI","Never pass 0 for retain-entries; use the dedicated purge command if you truly want to wipe","Add CI checks on scripts that compute retention values","Remember omitting the flag uses its default; only pass explicit positive values"],"tags":["cli","validation","argument","audit"],"backgroundTag":"invalid-flag-value","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}