windmill-labs/windmill · error

Error updating collection versions: {e}

Error message

Error updating collection versions: {e}

What it means

After pinning `roles`, add_versions_to_requirements_yaml pins the `collections` section and wraps any update_versions failure with 'Error updating collection versions:'. The inner cause is the same family: root not a map, a collection entry not a map, or a missing/non-string `name`. The wrapper identifies the failing section as collections.

Source

Thrown at backend/parsers/windmill-parser-yaml/src/lib.rs:931

pub fn add_versions_to_requirements_yaml(
    input: &str,
    role_versions: &HashMap<String, String>,
    collection_versions: &HashMap<String, String>,
) -> anyhow::Result<(String, String)> {
    let mut docs =
        YamlLoader::load_from_str(input).map_err(|e| anyhow!("YAML parse error: {}", e))?;
    let doc = &mut docs[0];

    let mut logs = String::new();

    logs.push_str(
        &update_versions("roles", doc, role_versions)
            .map_err(|e| anyhow!("Error updating role versions: {e}"))?,
    );
    logs.push_str(
        &update_versions("collections", doc, collection_versions)
            .map_err(|e| anyhow!("Error updating collection versions: {e}"))?,
    );

    if !logs.is_empty() {
        logs.push_str("WARNING: You might want to try adding manual versions for these, otherwise there could be breaking changes on deployed scripts\n");
    }

    let mut out_str = String::new();
    {
        let mut emitter = YamlEmitter::new(&mut out_str);
        emitter
            .dump(doc)
            .map_err(|e| anyhow!("YAML emit error: {}", e))?;
    }

    Ok((out_str, logs))
}

#[cfg(test)]

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the inner message after the prefix to find the exact structural fault.
  2. Ensure every collections entry is `- name: <fqcn>` with an optional `version:`.
  3. Quote names that YAML could infer as numbers/booleans.
  4. Validate the requirements file structure before deploy.

Example fix

# before
collections:
  - community.postgresql
# after
collections:
  - name: community.postgresql
    version: 3.0.0
Defensive patterns

Strategy: validation

Validate before calling

fn validate_collections(input: &str) -> Result<(), String> {
    let doc: serde_yaml::Value = serde_yaml::from_str(input).map_err(|e| e.to_string())?;
    let root = doc.as_mapping().ok_or("root must be a map")?;
    if let Some(items) = root.get("collections").and_then(|s| s.as_sequence()) {
        for e in items {
            if e.get("name").map(|n| n.is_string()) != Some(true) {
                return Err("each collection needs a string name".into());
            }
        }
    }
    Ok(())
}

Type guard

fn collections_are_pinnable(v: &serde_yaml::Value) -> bool {
    v.as_mapping().map(|m| m.get("collections").map(|c| c.as_sequence().map(|s| s.iter().all(|e| e.get("name").map(|n| n.is_string()).unwrap_or(false)).unwrap_or(true))).unwrap_or(true)).unwrap_or(false)
}

Try / catch

match pin_versions(input, &roles, &collections) {
    Err(e) if e.to_string().contains("Error updating collection versions") => {
        eprintln!("Collections section invalid (see inner message): entries need name fields\n{e}");
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling add_versions_to_requirements_yaml where the collections array contains bare strings (`- community.postgresql`), entries without a `name` field, or the document root is not a mapping at all.

Common situations: Collections written in short form (ansible-galaxy accepts them, this parser does not); entries with only `version:`; names parsed as non-strings (numeric collection names); hand-edited sections dropping the name key.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/2f62c9270974c992. Report an issue: GitHub.