windmill-labs/windmill · error
Missing `required` field on schema
Error message
Missing `required` field on schema
What it means
Raised by from_schema in windmill-common when the supplied JSON Schema has no `required` key. Windmill's restricted schema parser (draft 2020-12 only) demands an explicit required array and does not infer optionality, so a schema omitting it is rejected at parse time. This is a parser-capability guard on the schema input, not a data validation failure.
Source
Thrown at backend/windmill-common/src/schema.rs:526
Ok(())
}
pub fn from_schema(schema: &str) -> Result<Self, Error> {
let schema: Value = serde_json::from_str(schema)?;
if let Some(draft_version) = schema.get("$schema") {
match draft_version.as_str() {
Some("https://json-schema.org/draft/2020-12/schema") => (),
_ => return Err(anyhow!("Supplied schema draft version is unsuported").into()),
}
} else {
return Err(anyhow!("No draft version supplied").into());
}
let required: Vec<String> = schema
.get("required")
.ok_or(anyhow!("Missing `required` field on schema"))?
.as_array()
.ok_or(anyhow!("`required` field should be an array of strings"))?
.into_iter()
.map(|v| {
v.as_str()
.map(|s| s.to_string())
.ok_or(anyhow!("required field key is not a string"))
})
.collect::<Result<Vec<String>, anyhow::Error>>()?;
let properties = schema
.get("properties")
.ok_or(anyhow!("Missing `properties` field on schema"))?
.as_object()
.ok_or(anyhow!("`properties` field should be an object"))?;
let mut rules = vec![];
View on GitHub (pinned to e474e8803c)
Solutions
- Add an explicit top-level "required": [] (or list the required property names).
- Update the schema generator to always emit `required`, even when empty.
Example fix
// before
{"$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"a": {"type": "string"}}}
// after
{"$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"a": {"type": "string"}}, "required": []} Defensive patterns
Strategy: validation
Validate before calling
fn require_required_field(schema: &serde_json::Value) -> Result<(), String> {
if schema.get("required").is_none() {
Err("add top-level `required` array (use [] if nothing is mandatory)".into())
} else { Ok(()) }
} Type guard
fn has_required_field(schema: &serde_json::Value) -> bool {
schema.get("required").is_some()
} Try / catch
match Schema::from_schema(&schema_str) {
Ok(s) => s,
Err(e) if e.to_string().contains("Missing `required` field") => {
eprintln!("add a top-level `required` array, even if empty");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Always emit `required` in generated schemas, defaulting to []
- Never rely on the key being optional — this API requires it explicitly
When it happens
Trigger: Calling Schema::from_schema with a schema that has properties but no top-level `required` key, e.g. {"$schema":...,"type":"object","properties":{...}} with no `required`.
Common situations: Schemas where nothing is mandatory (authors omit `required` instead of using an empty array), schemas generated from TypeScript types with no required members, and schemas trimmed down by hand.
Related errors
- No draft version supplied
- Missing `properties` field on schema
- Missing `type` field
- Unsupported value for type field, expected string or string
- enum variants are not in an array
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/93b1938612d7b9fd.
Report an issue: GitHub.