windmill-labs/windmill · error

Missing `type` field

Error message

Missing `type` field

What it means

`SchemaValidationRule::from_value` first checks for a single string `type`. When absent (and the value is not a union handled earlier), it errors because Windmill cannot build validation rules for a schema with no declared type. This runs when apps/flows parse embedded JSON schemas (e.g. via reduce_app).

Source

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

            }
        }

        Ok(schema_rules)
    }

    fn from_value(val: &Value) -> Result<Vec<Self>, Error> {
        if let Some(any_of) = val.get("anyOf").and_then(|any_of| any_of.as_array()) {
            let mut r = vec![];

            for variant in any_of {
                r.push(SchemaValidationRule::from_value(variant)?);
            }
            return Ok(vec![SchemaValidationRule::IsUnionType(r)]);
        }

        let mut schema_rules = vec![];

        let typ = val.get("type").ok_or(anyhow!("Missing `type` field"))?;

        if let Some(typ) = typ.as_str() {
            schema_rules.append(&mut SchemaValidationRule::from_primitive(
                &JsonPrimitiveType::from_str(typ)?,
                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,
                    )
                })

View on GitHub (pinned to e474e8803c)

Solutions

  1. Add an explicit `"type": "string|number|integer|boolean|object|array"` to the schema node.
  2. If the value can be multiple types, supply `"type": [...]` array form (see error 939).
  3. If using object variants, wrap them in `oneOf` with titles so the union branch is taken.

Example fix

// before
{ "properties": { "a": { "type": "string" } } }
// after
{ "type": "object", "properties": { "a": { "type": "string" } } }
Defensive patterns

Strategy: validation

Validate before calling

const s = JSON.parse(schemaRaw);
const PRIMITIVES = ["string", "number", "integer", "boolean", "object", "array"];
if (!Array.isArray(s.type) && typeof s.type !== "string") {
  throw new Error("Schema node needs a string `type` (or a type array)");
}

Type guard

function hasDeclaredType(s) {
  return typeof s?.type === "string" || Array.isArray(s?.type);
}

Try / catch

try {
  await deployApp(app);
} catch (e) {
  if (String(e.message).includes("Missing `type` field")) {
    throw new Error("Add an explicit `type` to the offending schema node (Windmill does not infer types)");
  } else throw e;
}

Prevention

When it happens

Trigger: A schema node without a `type` field (and without the union/oneOf shapes handled before this branch), e.g. `{ "properties": {...} }` alone, parsed during app reduction or deployment.

Common situations: Schemas relying on implicit typing that Windmill does not support; partial schema fragments copied into Windmill; generator output omitting `type` when it can be inferred.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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