windmill-labs/windmill · error
Missing `properties` field on schema
Error message
Missing `properties` field on schema
What it means
from_schema requires a top-level `properties` object mapping property names to their sub-schemas. A schema with no `properties` key is rejected, even if empty properties would be semantically valid — an explicit "properties": {} is needed.
Source
Thrown at backend/windmill-common/src/schema.rs:539
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![];
for (key, val) in properties {
rules.push((
key.clone(),
SchemaValidationRule::from_value(val)
.map_err(|e| anyhow!("Problem making rule for {key}: {e}"))?,
));
}
Ok(Self { required, rules })
}
}
impl JsonPrimitiveType {View on GitHub (pinned to e474e8803c)
Solutions
- Add a top-level "properties" object with the property definitions (use {} if there are none).
- If the root value is not an object, this API is not the right fit — from_schema validates object-shaped arguments only.
Example fix
// before
{"$schema": "https://json-schema.org/draft/2020-12/schema", "required": []}
// after
{"$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {}, "required": []} Defensive patterns
Strategy: validation
Validate before calling
fn require_properties_field(schema: &serde_json::Value) -> Result<(), String> {
if schema.get("properties").is_none() {
Err("add top-level `properties` object (use {} if empty)".into())
} else { Ok(()) }
} Type guard
fn has_properties_object(schema: &serde_json::Value) -> bool {
schema.get("properties").map(|p| p.is_object()).unwrap_or(false)
} Try / catch
match Schema::from_schema(&schema_str) {
Ok(s) => s,
Err(e) if e.to_string().contains("Missing `properties` field") => {
eprintln!("add a top-level `properties` object before calling from_schema");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Always include properties, even as {} — this API does not accept its absence
- Confirm the root schema describes an object; other root shapes are unsupported here
When it happens
Trigger: Calling Schema::from_schema with a schema that lacks the top-level `properties` key, e.g. only $schema/type/required are present, or when properties were accidentally nested under a different key.
Common situations: Minimal or malformed schemas, schemas intended for array/primitive roots (which this API doesn't model — it validates objects), and schemas built dynamically where the properties step was skipped.
Related errors
- No draft version supplied
- Missing `required` 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/86a3a817fcf0713b.
Report an issue: GitHub.