{"record":{"id":"84d743bc5f8858f1","repo":"windmill-labs/windmill","slug":"failed-to-parse-yaml","errorCode":null,"errorMessage":"Failed to parse yaml: {}","messagePattern":"Failed to parse yaml: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-yaml/src/lib.rs","lineNumber":21,"sourceCode":"use anyhow::anyhow;\nuse serde::Serialize;\nuse serde_json::json;\nuse windmill_parser::{Arg, MainArgSignature, ObjectProperty, ObjectType, Typ};\nuse yaml_rust::{Yaml, YamlEmitter, YamlLoader};\n\npub mod asset_parser;\npub use asset_parser::parse_assets;\n\npub mod dbt;\npub use dbt::{\n    dbt_arg_schema, default_command as default_dbt_command, parse_dbt_descriptor, parse_dbt_sig,\n    DbtDescriptor, DbtEngine, DbtTestBehavior, DBT_COMMANDS, DBT_COMMAND_ARG, DBT_COMMAND_LABEL,\n    DBT_DEFAULT_WAREHOUSE,\n};\n\npub fn parse_ansible_sig(inner_content: &str) -> anyhow::Result<MainArgSignature> {\n    let docs = YamlLoader::load_from_str(inner_content)\n        .map_err(|e| anyhow!(\"Failed to parse yaml: {}\", e))?;\n\n    let mut delegating_to_git_repo = false;\n    if let Yaml::Hash(doc) = &docs[0] {\n        if let Some(v) = doc.get(&Yaml::String(\"delegate_to_git_repo\".to_string())) {\n            delegating_to_git_repo = extract_delegate_to_git_repo_details(v).is_some();\n        }\n    }\n\n    if docs.len() < 2 && !delegating_to_git_repo {\n        return Ok(MainArgSignature {\n            star_args: false,\n            star_kwargs: false,\n            args: vec![],\n            auto_kind: None,\n            has_preprocessor: None,\n            ..Default::default()\n        });\n    }","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-yaml/src/lib.rs#L3-L39","documentation":"parse_ansible_sig parses the Ansible script's inner content as YAML before extracting its signature (delegate_to_git_repo and arguments). The YamlLoader failed to parse the content, so the function returns this error wrapping the underlying serde-yaml message.","triggerScenarios":"Any call to parse_ansible_sig whose inner_content is not valid YAML — malformed indentation, bad types, tabs, duplicate keys, or an unclosed block — triggers the map_err on YamlLoader::load_from_str.","commonSituations":"Editing an Ansible windmill script in the UI and breaking indentation with spaces/tabs, pasting YAML with template syntax that breaks parsing, or trailing content after the document.","solutions":["Read the wrapped serde-yaml message for the exact line/column and fix the YAML syntax (typically indentation).","Replace tab characters with spaces.","Validate the YAML with a linter (e.g. yamllint) before deploying.","Ensure the document is a mapping at the root, since the code indexes docs[0] as a Hash."],"exampleFix":"# before\ndebuilder_to_git_repo:\n  repo: x\n    bad_indent\n# after\ndelegate_to_git_repo:\n  repo: x","handlingStrategy":"try-catch","validationCode":"if let Err(e) = serde_yml::from_str::<serde_yml::Value>(content) { /* surface e before calling parse_ansible_sig */ }","typeGuard":"fn is_mapping_root(docs: &[Yaml]) -> bool { matches!(docs.first(), Some(Yaml::Hash(_))) }","tryCatchPattern":"match parse_ansible_sig(content) {\n    Ok(sig) => sig,\n    Err(e) if e.to_string().starts_with(\"Failed to parse yaml\") => {\n        eprintln!(\"Fix YAML syntax: {e}\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Lint Ansible script YAML with yamllint before saving","Use spaces, never tabs, for indentation","Keep the root document a mapping","Validate in an editor with YAML syntax highlighting"],"tags":["yaml","ansible","parse-error","windmill-parser"],"backgroundTag":"yaml-parse-error","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}