{"record":{"id":"d8b189dfd573860a","repo":"windmill-labs/windmill","slug":"git-ssh-identity-file-must-be-a-string-path-to-a-w","errorCode":null,"errorMessage":"Git ssh identity file must be a string path to a Windmill variable/secret","messagePattern":"Git ssh identity file must be a string path to a Windmill variable/secret","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-yaml/src/lib.rs","lineNumber":612,"sourceCode":"    let mut out_str = String::new();\n    let mut emitter = YamlEmitter::new(&mut out_str);\n\n    for i in 1..docs.len() {\n        emitter.dump(&docs[i])?;\n    }\n    Ok((logs, Some(ret), out_str))\n}\n\nfn extract_ssh_identity(value: &Yaml, ret: &mut Vec<String>) -> anyhow::Result<()> {\n    let Yaml::Array(indentities) = value else {\n        return Err(anyhow!(\n            \"git_ssh_identity expects an array of windmill variables (or secrets) containing ssh IDs\"\n        ));\n    };\n\n    for r in indentities {\n        let Yaml::String(file_name) = r else {\n            return Err(anyhow!(\n                \"Git ssh identity file must be a string path to a Windmill variable/secret\"\n            ));\n        };\n\n        ret.push(file_name.clone());\n    }\n    Ok(())\n}\n\nfn extract_delegate_to_git_repo_details(value: &Yaml) -> Option<DelegateToGitRepoDetails> {\n    if let Yaml::Hash(v) = value {\n        if let Some(resource) = v\n            .get(&Yaml::String(\"resource\".to_string()))\n            .and_then(|s| s.as_str())\n            .map(|s| s.to_string())\n        {\n            let playbook = v\n                .get(&Yaml::String(\"playbook\".to_string()))","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-yaml/src/lib.rs#L594-L630","documentation":"extract_ssh_identity throws this when an element of the `git_ssh_identity` array is not a YAML string. Each element must be a string naming a Windmill variable/secret containing an SSH identity file; numbers, booleans, maps, or nested lists inside the array trigger this error.","triggerScenarios":"parse_ansible_reqs or parse_delegate_to_git_repo iterating a `git_ssh_identity` array encounters a non-string element (e.g. an unquoted value that YAML parses as an integer/boolean, a nested map, or a null `-` entry).","commonSituations":"Unquoted variable references starting with characters YAML treats specially; a list item left empty (`-`); accidentally nesting another list; pasting the variable's value instead of its path.","solutions":["Make every list item a quoted or plain string path to a Windmill variable/secret","Quote items that could be misparsed as numbers/booleans (e.g. '0123', 'yes')","Remove empty list entries","Verify no accidental nested list under git_ssh_identity"],"exampleFix":"# before\ngit_ssh_identity:\n  -\n\n# after\ngit_ssh_identity:\n  - u$ssh_identity_var","handlingStrategy":"type-guard","validationCode":"fn validate_ssh_identity_items(value: &Yaml) -> Result<(), String> {\n    if let Yaml::Array(items) = value {\n        for (i, it) in items.iter().enumerate() {\n            if !matches!(it, Yaml::String(_)) {\n                return Err(format!(\"git_ssh_identity[{}] is not a string\", i));\n            }\n        }\n    }\n    Ok(())\n}","typeGuard":"fn is_string(v: &Yaml) -> bool {\n    matches!(v, Yaml::String(_))\n}","tryCatchPattern":null,"preventionTips":["Quote list items that could parse as numbers or booleans","Remove empty `-` entries from the list","Each item must be a Windmill variable/secret path, not the secret's value"],"tags":["yaml","ansible","ssh","parser"],"backgroundTag":"yaml-schema-validation","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}