{"record":{"id":"e64ce779479922d0","repo":"ruvnet/RuView","slug":"invalid-automations-file-e","errorCode":null,"errorMessage":"invalid automations file {}: {e}","messagePattern":"invalid automations file (.+?): (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"v2/crates/homecore-server/src/main.rs","lineNumber":294,"sourceCode":"            limits: homecore_plugins::DiscoveryLimits::default(),\n        },\n    )\n    .await?;\n\n    // ── 4. Automation engine ────────────────────────────────────────\n    // Construct AND start the engine (HC-WS-03, ADR-161). `start()`\n    // spawns the state-change event loop + the 1 Hz wall-clock timer\n    // task so state/numeric/event AND time triggers all fire. The\n    // engine is kept alive for the process lifetime (it is moved into a\n    // long-lived binding); its background tasks run until the HomeCore\n    // broadcast channel closes at shutdown. No automations are loaded at\n    // boot yet (YAML loader is P-next); integrations register via\n    // `engine.register(..)`.\n    let automation_engine = AutomationEngine::new(hc.clone());\n    if let Some(path) = &cli.automations {\n        let raw = tokio::fs::read_to_string(path).await?;\n        let automations: Vec<homecore_automation::Automation> = serde_yaml::from_str(&raw)\n            .map_err(|e| anyhow::anyhow!(\"invalid automations file {}: {e}\", path.display()))?;\n        for automation in automations {\n            automation_engine.register(automation);\n        }\n    }\n    let _automation_task = automation_engine.start();\n    info!(\n        \"Automation engine started ({} automations registered) — \\\n         state/numeric/event + time triggers active\",\n        automation_engine.len()\n    );\n\n    // ── 5. Assist pipeline ──────────────────────────────────────────\n    // ── 6. HAP bridge surface ───────────────────────────────────────\n    // ── 7. REST + WS API ────────────────────────────────────────────\n    // Token provisioning closes audit findings HC-01/HC-02. If\n    // HOMECORE_TOKENS is set in the env, populate the store from\n    // its comma-separated list. Otherwise fall back to DEV mode\n    // (warn-on-each-request) so existing smoke tests still work.","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/v2/crates/homecore-server/src/main.rs#L276-L312","documentation":"Anyhow error wrapping a serde_yaml failure: the file given via --automations was read successfully (tokio::fs::read_to_string) but could not be deserialized into Vec<homecore_automation::Automation>. The message includes the path and the underlying serde error (line/column and the field that failed), and none of the automations load because parsing aborts before the register loop.","triggerScenarios":"YAML syntax errors (tabs, bad indentation, missing colon); schema mismatches -- top level is a mapping instead of a list, automation entries use wrong or renamed field names, or a value has the wrong type for the Automation struct.","commonSituations":"Hand-edited automation files introducing stray characters; upgrades that renamed Automation fields while old YAML keeps the previous names; copying examples from a different version of the project; editors inserting tabs.","solutions":["Read the {e} portion of the message -- serde_yaml names the line/column and the offending field; fix that spot first","Validate the file parses before startup: python -c 'import yaml,sys; yaml.safe_load(open(sys.argv[1]))' for syntax, then check structure against the Automation definition","Ensure the top level is a YAML sequence of automation mappings matching the current homecore-automation schema (field names and types)","After a version upgrade, re-check the automation file format against the release's documented schema"],"exampleFix":"# before (automations.yaml)\nautomation:\n  - name: lights-off\n    # error: invalid automations file automations.yaml: invalid type: map, expected a sequence\n\n# after (automations.yaml)\n- name: lights-off\n  trigger: { state: { entity: light.desk, to: 'off' } }\n  action: { service: light.turn_off, target: light.desk }","handlingStrategy":"validation","validationCode":"# preflight: syntax + shape check before handing the file to the server\npython3 - <<'EOF'\nimport yaml, sys\ndocs = yaml.safe_load(open(sys.argv[1]))\nassert isinstance(docs, list), 'automations file must be a top-level YAML list'\nfor a in docs:\n    assert isinstance(a, dict) and 'name' in a, f'bad automation entry: {a!r}'\nprint('automations OK:', len(docs))\nEOF\nhomecore-server --automations automations.yaml","typeGuard":null,"tryCatchPattern":"let automations: Vec<Automation> = match serde_yaml::from_str(&raw) {\n    Ok(v) => v,\n    Err(e) => {\n        tracing::error!(\"invalid automations file {path}: {e}; starting with 0 automations\");\n        Vec::new()\n    }\n};","preventionTips":["Lint automation YAML in CI (yamllint plus a schema check) before it reaches a server","After upgrading homecore, diff the Automation schema and migrate files in the same change","Rely on the {e} detail: serde_yaml reports exact line/column of the failure"],"tags":["rust","yaml","serde","automations","configuration","startup"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}