windmill-labs/windmill · error

Unsupported value for type field, expected string or string

Error message

Unsupported value for type field, expected string or string array

What it means

Windmill parses JSON Schema property definitions into validation rules via SchemaValidationRule::from_value. The `type` field must be either a string (e.g. "object") or an array of such strings (a type union); anything else (number, object, null) is rejected. This is a schema-authoring error detected when the schema is loaded, not when data is validated.

Source

Thrown at backend/windmill-common/src/schema.rs:181

                val,
            )?);
        } else if let Some(typ_arr) = typ.as_array() {
            let typ_arr = typ_arr
                .into_iter()
                .map(|v| {
                    SchemaValidationRule::from_primitive(
                        &JsonPrimitiveType::from_str(
                            v.as_str()
                                .ok_or(anyhow!("Expected array of strings for `type` field"))?,
                        )?,
                        v,
                    )
                })
                .collect::<Result<Vec<Vec<SchemaValidationRule>>, anyhow::Error>>()?;

            schema_rules.push(SchemaValidationRule::IsUnionType(typ_arr));
        } else {
            return Err(anyhow!(
                "Unsupported value for type field, expected string or string array"
            )
            .into());
        }

        if let Some(enum_variants) = val.get("enum") {
            let variants = enum_variants
                .as_array()
                .ok_or(anyhow!("enum variants are not in an array"))?
                .clone();
            schema_rules.push(SchemaValidationRule::StrictEnum(variants));
        }

        Ok(schema_rules)
    }

    fn apply_rule(&self, key: &str, val: &Value, required: bool) -> Result<(), Error> {
        if val.is_null() {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Set `type` to a supported string: object, array, string, number, integer, boolean, or null.
  2. If multiple types are intended, use an array of strings, e.g. "type": ["string","null"].
  3. If the property is a union of shapes, use `anyOf` with sub-schemas instead of a complex `type`.
  4. Remove the property or fix the generator/template that produced the malformed `type` value.

Example fix

// before
{"myProp": {"type": 1}}
// after
{"myProp": {"type": "integer"}}
Defensive patterns

Strategy: validation

Validate before calling

fn validate_type_field(prop: &serde_json::Value) -> Result<(), String> {
    let t = prop.get("type").ok_or("missing type")?;
    let ok = t.as_str().is_some()
        || t.as_array().map(|a| a.iter().all(|v| v.is_string())).unwrap_or(false);
    if ok { Ok(()) } else { Err("type must be a string or array of strings".into()) }
}

Type guard

fn has_valid_type(prop: &serde_json::Value) -> bool {
    match prop.get("type") {
        Some(v) if v.is_string() => true,
        Some(v) if v.is_array() => v.as_array().unwrap().iter().all(|x| x.is_string()),
        _ => false,
    }
}

Try / catch

match Schema::from_schema(&schema_str) {
    Ok(s) => s,
    Err(e) if e.to_string().contains("Unsupported value for type field") => {
        eprintln!("schema has a malformed `type` value: {e}");
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling SchemaValidationRule::from_value (indirectly through Schema::from_schema, e.g. when an app inline script's schema is reduced by reduce_app) with a property whose `type` is a non-string, non-array JSON value such as {"type": 1}, {"type": {"a":"b"}}, or {"type": true}.

Common situations: Hand-written or generated schemas where `type` was mistyped, a tool emitted `type: null` for optional fields, a schema generator produced a boolean-schema-like form, or someone confused `type` with `$ref`/`anyOf` composition.

Related errors


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