Hmbown/CodeWhale · error

refusing to import non-portable config path

Error message

refusing to import non-portable config path {dotted}

What it means

During prepare_import each table entry is screened with nonportable_path_reason(key) and value_rejection_reason(key, value); if either rejects the entry, the import is refused because that dotted config path is not portable across machines (e.g. machine-local paths, secrets, or values of the wrong shape). The import aborts before any write rather than silently dropping entries.

Solutions

  1. Open the bundle and remove/replace the offending `section.key` entry, then re-import.
  2. Move machine-specific values out of the bundle — set them locally after import instead of shipping them in the file.
  3. Re-export with `config export --portable` so the exporter strips non-portable paths at source.

Example fix

// before (bundle.toml)
[settings]
history_path = "/home/alice/.local/share/codewhale"
// after
[settings]
# history_path removed: machine-local; configure per machine
Defensive patterns

Strategy: validation

Validate before calling

for (k, v) in bundle_table.iter() {
    if nonportable_path_reason(k).is_some() || value_rejection_reason(k, v).is_some() {
        eprintln!("non-portable entry: {k}");
    }
}

Type guard

fn all_entries_portable(table: &toml::Table) -> bool {
    table.iter().all(|(k, v)| nonportable_path_reason(k).is_none() && value_rejection_reason(k, v).is_none())
}

Try / catch

if let Err(e) = run_import(&args, &store) {
    if e.to_string().starts_with("refusing to import non-portable config path") {
        eprintln!("strip the named path from the bundle and retry");
    }
}

Prevention

When it happens

Trigger: Importing a bundle whose config table contains a key flagged as non-portable (machine-specific path keys) or a value whose type/content is rejected for that key; raised from prepare_import via run_import/apply_bundle.

Common situations: Hand-editing a bundle and adding absolute filesystem paths or credential-like values; bundles generated on another OS where a path key is non-portable; exporting older config formats whose value types no longer validate.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/8f5ba5fac38b3969. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/config_bundles.rs:1188

    let mut candidate = config_from_document(&document.to_string())?;
    let mut model_edits = Vec::<(String, String, String)>::new();
    let mut selected_provider = None;
    for (section, table) in [
        ("preferences", &bundle.preferences),
        ("profiles", &bundle.profiles),
        ("plugins", &bundle.plugins),
        ("project", &bundle.project),
        ("global", &bundle.global),
    ] {
        if !section_applies(section, scope) {
            continue;
        }
        for (key, value) in &table.entries {
            let dotted = format!("{section}.{key}");
            if nonportable_path_reason(key).is_some()
                || value_rejection_reason(key, value).is_some()
            {
                bail!("refusing to import non-portable config path {dotted}");
            }
            if key == "provider" {
                selected_provider = Some(
                    value
                        .as_str()
                        .ok_or_else(|| anyhow!("config entry {dotted:?} must be a string"))?,
                );
                continue;
            }
            collect_model_edits(&dotted, key, value, &mut model_edits)?;
            if codewhale_tui::route_preferences::is_route_key(key) {
                continue;
            }
            apply_config_value(&mut candidate, key, value)?;
        }
    }
    document = toml::to_string(&toml::Value::Table(config_document(&candidate)?))?
        .parse()

View on GitHub (pinned to 73e0f67d83)