unicity-aos/capsule-identity · warning

Failed to parse during auto-detect

Error message

Failed to parse {SPARK_CONFIG_PATH} during auto-detect: {e}

What it means

This is a warning logged during automatic identity detection in build_prompt_text_with_spark_loader when the spark.toml config file at SPARK_CONFIG_PATH exists but cannot be parsed as valid TOML (toml::from_str returned Err). The loader treats the failure as non-fatal: it logs the parse error and continues without loading the saved identity, so the user goes through onboarding again. The error message interpolates the underlying TOML parse error `e` describing the exact syntax or type problem.

Solutions

  1. Open the file at SPARK_CONFIG_PATH and fix the TOML syntax error reported in the message (line/column are included in `e`).
  2. Verify each field matches SparkConfig's expected types (e.g. callsign must be a string) and that unknown/renamed fields are removed or allowed.
  3. Regenerate the config by letting the app run onboarding again (delete the corrupt file; it will be re-created on identity save).
  4. If you control writes to spark.toml, serialize with toml::to_string from SparkConfig instead of hand-writing the file, and validate after writing.

Example fix

# before (spark.toml with broken syntax)
[callsign]
name = "Nova"

# after (valid for SparkConfig)
callsign = "Nova"
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on auto-detect, pre-validate the config file.
let raw = std::fs::read_to_string(SPARK_CONFIG_PATH).ok()?;
match toml::from_str::<SparkConfig>(&raw) {
    Ok(cfg) if !cfg.callsign.is_empty() => Some(cfg),
    _ => None, // fall back to onboarding instead of a silent skip
}

Type guard

fn is_valid_spark_config(raw: &str) -> bool {
    toml::from_str::<SparkConfig>(raw)
        .map(|c| !c.callsign.is_empty())
        .unwrap_or(false)
}

Try / catch

// Rust has no try/catch; handle the Result explicitly
match toml::from_str::<SparkConfig>(&content) {
    Ok(config) if !config.callsign.is_empty() => { /* use config */ }
    Ok(_) => { /* empty callsign: stub, run onboarding */ }
    Err(e) => log::warn(format!("Bad spark.toml: {e}; running onboarding")),
}

Prevention

When it happens

Trigger: Calling build_prompt_text (directly or via the prompt-building paths) when a spark.toml file exists at SPARK_CONFIG_PATH but toml::from_str fails on its contents — e.g. malformed TOML syntax, a field with the wrong type (callsign defined as a non-string), or a schema/type mismatch against SparkConfig's serde definitions.

Common situations: A user hand-edited spark.toml and introduced a syntax error (missing quote, bad section header); a config file written by an older/newer version with fields whose types changed; the file was corrupted or truncated on disk; a tools-generated config wrote invalid TOML.

Understand the failure class

Related errors


AI-assisted analysis of unicity-aos/capsule-identity@1364a437f3 (2026-09-13). Data as JSON: /api/errors/f2e7bb9e0acc335b. Report an issue: GitHub.

Appendix: source

Thrown at src/lib.rs:189

        );

        // Auto-detect an existing spark.toml when KV state says not yet onboarded.
        // This makes the capsule resilient to KV resets: if the file exists and
        // parses successfully we treat the user as onboarded without requiring
        // an explicit `identity-import`.
        if !self.onboarded
            && let Some(content) = load_spark()
        {
            // Parse directly instead of going through parse_spark_toml (which
            // falls back to a default with a non-empty callsign on error).
            match toml::from_str::<SparkConfig>(&content) {
                Ok(config) if !config.callsign.is_empty() => {
                    self.spark = config;
                    self.onboarded = true;
                }
                Ok(_) => {} // Empty callsign — treat as stub, don't onboard.
                Err(e) => {
                    log::warn(format!(
                        "Failed to parse {SPARK_CONFIG_PATH} during auto-detect: {e}"
                    ));
                }
            }
        }

        if self.onboarded {
            // Prepend the established identity preamble.
            let opening = self.spark.build_preamble();
            prompt = format!("{opening}\n\n{prompt}");
        } else {
            // No preamble — don't anchor the model to a name before onboarding.
            prompt.push_str("\n\n");
            prompt.push_str(ONBOARDING_PROMPT);
        }

        prompt
    }

View on GitHub (pinned to 1364a437f3)