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

  1. Read the logged {err} detail and fix the filesystem cause (permissions, disk space).
  2. Ensure $HOME points to a writable directory, or run with a writable HOME.
  3. Remove or fix conflicting files/directories at the destination config path.
  4. 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

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


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)