{"record":{"id":"2eed509fd2bb5673","repo":"unicity-aos/capsule-identity","slug":"failed-to-parse-spark-toml-using-defaults-e","errorCode":null,"errorMessage":"Failed to parse spark.toml, using defaults: {e}","messagePattern":"Failed to parse spark\\.toml, using defaults: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/lib.rs","lineNumber":279,"sourceCode":"    pub fn save_identity(&mut self, args: SparkConfig) -> Result<serde_json::Value, SysError> {\n        self.spark = args;\n        self.onboarded = true;\n\n        // Persist to spark.toml so identity survives KV resets.\n        let toml = self.spark.to_toml();\n        fs::write(SPARK_CONFIG_PATH, toml.as_bytes())?;\n\n        Ok(serde_json::json!({\n            \"status\": \"ok\",\n            \"callsign\": self.spark.callsign,\n        }))\n    }\n}\n\n/// Parse spark.toml into a `SparkConfig`.\nfn parse_spark_toml(content: &str) -> SparkConfig {\n    toml::from_str(content).unwrap_or_else(|e| {\n        log::warn(format!(\"Failed to parse spark.toml, using defaults: {e}\"));\n        SparkConfig::default()\n    })\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    fn configured_identity() -> SparkConfig {\n        SparkConfig {\n            callsign: \"Lyra\".into(),\n            class: \"a precise concierge agent\".into(),\n            aura: \"Calm, direct, and context aware.\".into(),\n            signal: \"Use short answers unless detail is needed.\".into(),\n            core: \"Preserve user boundaries.\".into(),\n        }\n    }\n","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/unicity-aos/capsule-identity/blob/1364a437f30122558a70ad703acc23d48f144ee6/src/lib.rs#L261-L297","documentation":"parse_spark_toml parses spark.toml content into a SparkConfig via toml::from_str. When parsing fails, it logs this warning and falls back to SparkConfig::default() instead of propagating the error, so the caller (handle_command) always receives a valid config. The interpolated `e` carries the underlying serde/TOML error detailing why deserialization failed.","triggerScenarios":"Calling handle_command with a command that routes through parse_spark_toml on spark.toml content that toml::from_str cannot deserialize: invalid TOML syntax, wrong field types relative to SparkConfig, or incompatible/unknown field structure for the current schema.","commonSituations":"Hand-edited spark.toml with syntax mistakes; config written by an older release whose fields were renamed or retyped; a partially written/corrupted file (e.g. crash mid-write); copy-pasting config with mismatched quotes or indentation in TOML.","solutions":["Fix the TOML syntax error at the location given in the parse error `e` inside the logged message.","Check that all fields conform to SparkConfig's serde types and remove obsolete or mistyped fields.","Replace the file with SparkConfig::default() output (serialize via toml::to_string) and re-add settings one at a time, re-running to confirm each parses.","For callers needing the exact problem surfaced, consider changing parse_spark_toml to return Result<SparkConfig, toml::de::Error> rather than silently defaulting, or at least surface the warning in command output."],"exampleFix":"// before: silent fallback\ntoml::from_str(content).unwrap_or_else(|e| {\n    log::warn(format!(\"Failed to parse spark.toml, using defaults: {e}\"));\n    SparkConfig::default()\n})\n\n// after: caller can see and handle the failure\nmatch toml::from_str::<SparkConfig>(content) {\n    Ok(cfg) => cfg,\n    Err(e) => {\n        log::warn(format!(\"Failed to parse spark.toml, using defaults: {e}\"));\n        SparkConfig::default()\n    }\n}","handlingStrategy":"validation","validationCode":"// Validate before passing content to the parser\nfn validate_spark_toml(content: &str) -> Result<SparkConfig, toml::de::Error> {\n    toml::from_str(content)\n}\n// caller:\nlet cfg = validate_spark_toml(&content)?; // or handle Err explicitly","typeGuard":"fn parses_as_spark_config(content: &str) -> bool {\n    toml::from_str::<SparkConfig>(content).is_ok()\n}","tryCatchPattern":"// Handle the Err branch explicitly instead of trusting the silent default\nlet config = toml::from_str::<SparkConfig>(content)\n    .unwrap_or_else(|e| {\n        log::warn(format!(\"spark.toml invalid ({e}); defaults in effect\"));\n        SparkConfig::default()\n    });","preventionTips":["Write spark.toml programmatically with toml::to_string from SparkConfig; avoid manual edits.","Round-trip check (parse immediately after write) whenever the file changes.","In CI or startup checks, parse the config and fail fast with the detailed serde error message.","Guard against truncated writes by writing to a temp file and atomically renaming it into place."],"tags":["toml","config","parsing","fallback","rust"],"backgroundTag":"toml-parse-error","analyzedSha":"1364a437f30122558a70ad703acc23d48f144ee6","analyzedAt":"2026-09-13T03:17:48.802Z","contentChangedAt":"2026-09-13T03:17:48.802Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}