Hmbown/CodeWhale · warning
Failed to create first-run config file
Error message
Failed to create first-run config file: {err} What it means
On first launch the TUI migrates the config directory (e.g. from an older location to ~/.codewhale/) via codewhale_config::migrate_config_if_needed(). If that migration fails, a non-fatal warning "Failed to create first-run config file: {err}" is logged and startup continues. Existing installs keep working; the new-location config may be missing or stale.
Solutions
- Read the logged {err} detail and fix the filesystem cause (permissions, disk space).
- Ensure $HOME points to a writable directory, or run with a writable HOME.
- Remove or fix conflicting files/directories at the destination config path.
- Create the config manually at ~/.codewhale/ if migration cannot run; the warning is non-fatal.
Example fix
// before (unwritable) HOME=/nonexistent app // after HOME=/home/user app
Defensive patterns
Strategy: validation
Validate before calling
let home = std::env::var("HOME")?; assert_writable_dir(&home)?; Try / catch
match migrate_config_if_needed() { Err(err) => eprintln!("using existing config; migration failed: {err}"), _ => {} } Prevention
- Run the app with a writable HOME.
- Never run as root in a way that leaves root-owned files in the config directory.
- Pre-provision ~/.codewhale/ on managed/container installs.
When it happens
Trigger: codewhale_config::migrate_config_if_needed() returns Err during first-run bootstrap in crates/tui/src/lib.rs (~11205) — e.g. unwritable home directory, existing file at the destination blocking creation, or permission errors.
Common situations: Read-only or full HOME; stale config file/directory already at the target path with wrong permissions; running under a sandboxed service account without a writable home; container images with $HOME unset.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Config migration skipped
- Antigravity is a retired, non-runnable legacy provider…
- Antigravity is a retired, non-runnable legacy provider…
- Choose a model for the destination provider before…
- Codewhale credentials directory cannot be a volume root
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/5ed2637c484733b0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/lib.rs:11199
|| crate::config::explicit_launch_model_override().is_some();
apply_selected_fleet_operator_for_launch(
&mut merged_config,
&workspace,
explicit_route_override,
false,
)?;
}
let config = &merged_config;
initialize_cloud_facts(config);
if !cli.skip_onboarding {
match crate::config::ensure_config_file_exists(cli.config.clone()) {
Ok(Some(path)) => logging::info(format!(
"Created first-run config file at {}",
path.display()
)),
Ok(None) => {}
Err(err) => logging::warn(format!("Failed to create first-run config file: {err}")),
}
}
// v0.8.44: migrate config from ~/.deepseek/ to ~/.codewhale/ on first
// launch. Non-fatal — existing installs keep working either way.
match codewhale_config::migrate_config_if_needed() {
Ok(Some(migration)) => {
eprintln!("{}", migration.user_notice());
}
Ok(None) => {}
Err(err) => logging::warn(format!("Config migration skipped: {err}")),
}
let model = config.default_model();
let provider = config.api_provider();
let max_subagents = cli.max_subagents.map_or_else(
|| config.max_subagents_for_provider(provider),
|value| value.clamp(1, MAX_SUBAGENTS),View on GitHub (pinned to 433685b202)