{"record":{"id":"6e0d7e3934d17c88","repo":"Hmbown/CodeWhale","slug":"no-loaded-config-file-can-receive-this-confirmation","errorCode":null,"errorMessage":"No loaded config file can receive this confirmation","messagePattern":"No loaded config file can receive this confirmation","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/redaction_gate.rs","lineNumber":191,"sourceCode":"\n/// Supporting hint in the muted lane.\nfn wrap_body_muted(lines: &mut Vec<Line<'static>>, app: &App, id: MessageId, width: usize) {\n    let text = app.tr(id);\n    for segment in wrap_words(&text, width) {\n        lines.push(Line::from(Span::styled(\n            segment,\n            Style::default().fg(palette::TEXT_MUTED),\n        )));\n    }\n}\n\n/// Persist the confirmation and return the written receipt path. Called after\n/// the user picks the explicit \"confirm\" action.\npub fn record_confirmation(config: &crate::config::Config) -> anyhow::Result<std::path::PathBuf> {\n    let path = config\n        .loaded_config_path\n        .as_deref()\n        .ok_or_else(|| anyhow::anyhow!(\"No loaded config file can receive this confirmation\"))?;\n    codewhale_config::redaction::record_model_bound_disabled_confirmation(path)\n        .map_err(anyhow::Error::from)\n}\n\n// The \"keep masking\" answer persists nothing and rewrites no file: the\n// current launch stays on the safe default, and because the config field\n// still requests `\"disabled\"`, the gate asks again on the next launch until\n// the user confirms or edits the field back to `\"enabled\"`. The event loop\n// implements this inline (it only clears the gate flag); this module-level\n// contract comment is where the semantics live.\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::config::Config;\n    use crate::tui::app::TuiOptions;\n    use crate::tui::views::action_footer_lines;\n    use std::path::PathBuf;","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/redaction_gate.rs#L173-L209","documentation":"record_confirmation persists the user's explicit 'disable model-bound redaction' confirmation into the config file that was loaded at startup. If no config file was loaded (e.g. all defaults, or config came from env/flags), there is no file to write the receipt into and the function refuses.","triggerScenarios":"Calling record_confirmation with a Config whose loaded_config_path is None — launched without a config file, with --no-config, or in a test/embedded context where Config was constructed programmatically.","commonSituations":"User runs Codewhale without any config file and then confirms the redaction prompt; config loaded purely from environment; headless/embedded usage.","solutions":["Launch Codewhale with a real config file (default path or --config) so confirmations have somewhere to persist","Create a minimal config file at the default location before confirming","Programmatically set loaded_config_path (or write the confirmation via codewhale_config::redaction::record_model_bound_disabled_confirmation directly to a chosen path)"],"exampleFix":"// before\nlet receipt = redaction_gate::record_confirmation(&config)?;\n// after\nif config.loaded_config_path.is_none() {\n    anyhow::bail!(\"Start with a config file to record this confirmation.\");\n}\nlet receipt = redaction_gate::record_confirmation(&config)?;","handlingStrategy":"validation","validationCode":"fn can_record_confirmation(config: &Config) -> bool {\n    config.loaded_config_path.is_some()\n}","typeGuard":null,"tryCatchPattern":"match redaction_gate::record_confirmation(&config) {\n    Err(e) if e.to_string().contains(\"No loaded config file\") => {\n        eprintln!(\"Launch with a config file to persist this confirmation.\");\n    }\n    r => r?,\n}","preventionTips":["Always launch with a config file if you intend to respond to redaction prompts","Check loaded_config_path before presenting the confirm action in UIs","Persist programmatic confirmations directly via the redaction API with an explicit path"],"tags":["config","redaction","missing-file"],"backgroundTag":"missing-config-file","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}