windmill-labs/windmill · error

Should be a Map

Error message

Should be a Map

What it means

parse_git_repo throws 'Should be a Map' when an element of the `git_repos` array is not a YAML mapping (hash). Each repo entry must be a map with keys like `url`, `target`, and optionally `branch`/`commit`. Scalars, strings, or sequences in the list fail the `Yaml::Hash` destructuring.

Source

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

                .unwrap_or(false);

            return Some(DelegateToGitRepoDetails {
                resource,
                playbook,
                commit,
                inventories_location,
                vars_location,
                ansible_cfg,
                install_requirements,
            });
        }
    }
    return None;
}

fn parse_git_repo(r: &Yaml) -> anyhow::Result<GitRepo> {
    let Yaml::Hash(repo) = r else {
        return Err(anyhow!("Should be a Map"));
    };

    let url = repo
        .get(&Yaml::String("url".to_string()))
        .and_then(|v| v.as_str())
        .map(|s| s.to_string())
        .ok_or(anyhow!("Expected `url` field"))?;

    let target_path = repo
        .get(&Yaml::String("target".to_string()))
        .and_then(|v| v.as_str())
        .map(|s| s.to_string())
        .ok_or(anyhow!(
            "Expected `target` field (target directory for cloning the repo)"
        ))?;

    let branch = repo
        .get(&Yaml::String("branch".to_string()))

View on GitHub (pinned to e474e8803c)

Solutions

  1. Convert each entry into a map: `- url: <repo-url>` with `target` under it
  2. Do not list raw URL strings; the parser has no shorthand for them
  3. Check indentation so each repo's keys belong to the same list item
  4. Remove empty or null list entries

Example fix

# before
git_repos:
  - https://github.com/org/repo.git

# after
git_repos:
  - url: https://github.com/org/repo.git
    target: repo
Defensive patterns

Strategy: validation

Validate before calling

fn validate_git_repo_entries(value: &Yaml) -> Result<(), String> {
    if let Yaml::Array(repos) = value {
        for (i, r) in repos.iter().enumerate() {
            if !matches!(r, Yaml::Hash(_)) {
                return Err(format!("git_repos[{}] is not a map; use `- url: ...` list items", i));
            }
        }
    }
    Ok(())
}

Type guard

fn is_yaml_map(v: &Yaml) -> bool {
    matches!(v, Yaml::Hash(_))
}

Prevention

When it happens

Trigger: parse_ansible_reqs passes each `git_repos` item to parse_git_repo; an item that is a plain string URL, a number, a list, or null hits the `Yaml::Hash` else-branch and returns this error (later wrapped as 'Failed to parse git repo: Should be a Map').

Common situations: Listing bare URLs (`- https://github.com/org/repo.git`) instead of repo maps; wrong indentation turning a map into a multi-item list fragment; a null entry from an empty list item.

Related errors


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