windmill-labs/windmill · error

Invalid field in `mode`, expected integer like 0o644

Error message

Invalid field in `mode`, expected integer like 0o644

What it means

Windmill's YAML parser parses file resources for Ansible-style file deployments. The optional `mode` field controls Unix file permissions and must be either a YAML integer or a string parseable as an octal/binary number (e.g. "0o644"). This error is thrown in parse_file_resource when the `mode` key is present but its value is neither a Yaml::Integer nor a Yaml::String — e.g. a boolean, null, sequence, or map.

Source

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

                            target_path
                        )
                    })?
                }
                Yaml::String(s) => {
                    let val = if s.starts_with("0b") {
                        u32::from_str_radix(&s[2..], 2)
                    } else if s.starts_with("0o") {
                        u32::from_str_radix(&s[2..], 8)
                    } else if s.starts_with("0") {
                        u32::from_str_radix(&s[1..], 8)
                    } else {
                        u32::from_str_radix(s, 8)
                    };

                    val.map_err(|e| anyhow!("Error parsing permission mode value {s}: {e}"))?
                }
                _ => {
                    return Err(anyhow!("Invalid field in `mode`, expected integer like 0o644"));
                }
            };
            if mode_val <= 0o777 {
                mode = Some(mode_val);
            } else {
                return Err(anyhow!("The provided value for `mode` is too big. Make sure that you are using the octal prefix (0o), e.g. `mode: 0o644`"));
            }
        }

        if let Some(Yaml::String(resource_path)) = f.get(&Yaml::String("resource".to_string())) {
            return Ok(FileResource {
                resource_path: ResourceOrVariablePath::Resource(resource_path.clone()),
                target_path,
                mode,
            });
        }
        if let Some(Yaml::String(resource_path)) = f.get(&Yaml::String("variable".to_string())) {
            return Ok(FileResource {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Set `mode` to a YAML integer (e.g. `mode: 420` for 0o644) or a quoted octal string (e.g. `mode: "0o644"`).
  2. Remove any surrounding brackets/braces so the value is a scalar, not a list or map.
  3. If you intended 'off'/'on', quote it or use a numeric mode instead — YAML booleans are rejected here.
  4. Ensure the `mode` key has a value on the same line; an empty key parses as null and fails.

Example fix

# before
files:
  - target: /etc/app.conf
    mode:
      perms: 644
# after
files:
  - target: /etc/app.conf
    mode: "0o644"
Defensive patterns

Strategy: validation

Validate before calling

fn validate_mode(v: &serde_yaml::Value) -> Result<(), String> {
    match v.get("mode") {
        None => Ok(()),
        Some(serde_yaml::Value::Number(n)) if n.as_u64().map(|x| x <= 0o777).unwrap_or(false) => Ok(()),
        Some(serde_yaml::Value::String(s)) if s.starts_with("0o") || s.starts_with("0b") || s.starts_with("0") => Ok(()),
        Some(other) => Err(format!("mode must be an int or octal string, got: {other:?}")),
    }
}

Type guard

fn is_valid_mode(v: &serde_yaml::Value) -> bool {
    matches!(v, serde_yaml::Value::Number(_) | serde_yaml::Value::String(_))
}

Try / catch

match parse_and_deploy(yaml) {
    Err(e) if e.to_string().contains("Invalid field in `mode`") => {
        eprintln!("Fix `mode` to an integer or octal string like \"0o644\"\n{e}");
    }
    Err(e) => return Err(e),
    Ok(v) => Ok(v),
}

Prevention

When it happens

Trigger: Calling parse_file_resource (via YAML file-resource parsing during script/app deploy) with an entry like `mode: [644]`, `mode: true`, `mode: null`, or a nested map under `mode`. Any non-scalar, non-string, non-integer value hits the `_` catch-all match arm.

Common situations: Quoting mistakes that turn `mode: 0644` into something YAML type-infers as boolean (e.g. `mode: no` / `mode: on` become Yaml::Boolean); copy-pasting a JSON array or object into the mode field; editors that autoformat `0o644` into a list; leaving `mode:` with no value (Yaml::Null).

Related errors


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