{"record":{"id":"86a3a817fcf0713b","repo":"windmill-labs/windmill","slug":"missing-properties-field-on-schema","errorCode":null,"errorMessage":"Missing `properties` field on schema","messagePattern":"Missing `properties` field on schema","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-common/src/schema.rs","lineNumber":539,"sourceCode":"            return Err(anyhow!(\"No draft version supplied\").into());\n        }\n\n        let required: Vec<String> = schema\n            .get(\"required\")\n            .ok_or(anyhow!(\"Missing `required` field on schema\"))?\n            .as_array()\n            .ok_or(anyhow!(\"`required` field should be an array of strings\"))?\n            .into_iter()\n            .map(|v| {\n                v.as_str()\n                    .map(|s| s.to_string())\n                    .ok_or(anyhow!(\"required field key is not a string\"))\n            })\n            .collect::<Result<Vec<String>, anyhow::Error>>()?;\n\n        let properties = schema\n            .get(\"properties\")\n            .ok_or(anyhow!(\"Missing `properties` field on schema\"))?\n            .as_object()\n            .ok_or(anyhow!(\"`properties` field should be an object\"))?;\n\n        let mut rules = vec![];\n\n        for (key, val) in properties {\n            rules.push((\n                key.clone(),\n                SchemaValidationRule::from_value(val)\n                    .map_err(|e| anyhow!(\"Problem making rule for {key}: {e}\"))?,\n            ));\n        }\n\n        Ok(Self { required, rules })\n    }\n}\n\nimpl JsonPrimitiveType {","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-common/src/schema.rs#L521-L557","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n{\"$schema\": \"https://json-schema.org/draft/2020-12/schema\", \"required\": []}\n// after\n{\"$schema\": \"https://json-schema.org/draft/2020-12/schema\", \"properties\": {}, \"required\": []}","handlingStrategy":"validation","validationCode":"fn require_properties_field(schema: &serde_json::Value) -> Result<(), String> {\n    if schema.get(\"properties\").is_none() {\n        Err(\"add top-level `properties` object (use {} if empty)\".into())\n    } else { Ok(()) }\n}","typeGuard":"fn has_properties_object(schema: &serde_json::Value) -> bool {\n    schema.get(\"properties\").map(|p| p.is_object()).unwrap_or(false)\n}","tryCatchPattern":"match Schema::from_schema(&schema_str) {\n    Ok(s) => s,\n    Err(e) if e.to_string().contains(\"Missing `properties` field\") => {\n        eprintln!(\"add a top-level `properties` object before calling from_schema\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["json-schema","schema-validation","missing-field","windmill"],"backgroundTag":"missing-schema-properties","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}