Hmbown/CodeWhale · error
No loaded config file can receive this confirmation
Error message
No loaded config file can receive this confirmation
What it means
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.
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)
Example fix
// before
let receipt = redaction_gate::record_confirmation(&config)?;
// after
if config.loaded_config_path.is_none() {
anyhow::bail!("Start with a config file to record this confirmation.");
}
let receipt = redaction_gate::record_confirmation(&config)?; Defensive patterns
Strategy: validation
Validate before calling
fn can_record_confirmation(config: &Config) -> bool {
config.loaded_config_path.is_some()
} Try / catch
match redaction_gate::record_confirmation(&config) {
Err(e) if e.to_string().contains("No loaded config file") => {
eprintln!("Launch with a config file to persist this confirmation.");
}
r => r?,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: User runs Codewhale without any config file and then confirms the redaction prompt; config loaded purely from environment; headless/embedded usage.
Related errors
- a CNB access token is not configured in the Codewhale…
- account_agent_model_unconfigured
- active profile is missing or malformed
- advisor model ` ` resolved only to a custom provider kind…
- agent profile path is not a directory
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/6e0d7e3934d17c88.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/redaction_gate.rs:191
/// Supporting hint in the muted lane.
fn wrap_body_muted(lines: &mut Vec<Line<'static>>, app: &App, id: MessageId, width: usize) {
let text = app.tr(id);
for segment in wrap_words(&text, width) {
lines.push(Line::from(Span::styled(
segment,
Style::default().fg(palette::TEXT_MUTED),
)));
}
}
/// Persist the confirmation and return the written receipt path. Called after
/// the user picks the explicit "confirm" action.
pub fn record_confirmation(config: &crate::config::Config) -> anyhow::Result<std::path::PathBuf> {
let path = config
.loaded_config_path
.as_deref()
.ok_or_else(|| anyhow::anyhow!("No loaded config file can receive this confirmation"))?;
codewhale_config::redaction::record_model_bound_disabled_confirmation(path)
.map_err(anyhow::Error::from)
}
// The "keep masking" answer persists nothing and rewrites no file: the
// current launch stays on the safe default, and because the config field
// still requests `"disabled"`, the gate asks again on the next launch until
// the user confirms or edits the field back to `"enabled"`. The event loop
// implements this inline (it only clears the gate flag); this module-level
// contract comment is where the semantics live.
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use crate::tui::app::TuiOptions;
use crate::tui::views::action_footer_lines;
use std::path::PathBuf;View on GitHub (pinned to 73e0f67d83)