{"record":{"id":"eef212e5f183a8ab","repo":"windmill-labs/windmill","slug":"required-field-should-be-an-array-of-strings","errorCode":null,"errorMessage":"`required` field should be an array of strings","messagePattern":"`required` field should be an array of strings","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-common/src/schema.rs","lineNumber":528,"sourceCode":"    }\n\n    pub fn from_schema(schema: &str) -> Result<Self, Error> {\n        let schema: Value = serde_json::from_str(schema)?;\n\n        if let Some(draft_version) = schema.get(\"$schema\") {\n            match draft_version.as_str() {\n                Some(\"https://json-schema.org/draft/2020-12/schema\") => (),\n                _ => return Err(anyhow!(\"Supplied schema draft version is unsuported\").into()),\n            }\n        } else {\n            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((","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-common/src/schema.rs#L510-L546","documentation":"The top-level `required` key exists but is not a JSON array. from_schema calls as_array on it and rejects any non-array value. Additionally, though the message says 'array of strings', the element check surfaces separately as 'required field key is not a string' (error 946).","triggerScenarios":"Calling Schema::from_schema with \"required\": \"a\" (a string), \"required\": {\"a\": true}, or \"required\": true — any non-array JSON value at the top-level `required` key.","commonSituations":"Confusing JSON Schema `required` (array) with OpenAPI-style per-property required: true, or schemas authored by tools expecting draft semantics where required lives inside each property.","solutions":["Change `required` to a JSON array of property-name strings, e.g. \"required\": [\"a\",\"b\"].","If migrating from OpenAPI, remove per-property \"required\": true and list those names in the top-level array instead."],"exampleFix":"// before\n{\"properties\": {\"a\": {\"type\": \"string\", \"required\": true}}}\n// after\n{\"properties\": {\"a\": {\"type\": \"string\"}}, \"required\": [\"a\"]}","handlingStrategy":"type-guard","validationCode":"fn validate_required_is_array(schema: &serde_json::Value) -> Result<(), String> {\n    match schema.get(\"required\") {\n        Some(r) if r.is_array() => Ok(()),\n        Some(_) => Err(\"`required` must be a JSON array of strings\".into()),\n        None => Err(\"missing `required`\".into()),\n    }\n}","typeGuard":"fn required_is_string_array(schema: &serde_json::Value) -> bool {\n    schema.get(\"required\")\n        .and_then(|r| r.as_array())\n        .map(|a| a.iter().all(|v| v.is_string()))\n        .unwrap_or(false)\n}","tryCatchPattern":"match Schema::from_schema(&schema_str) {\n    Ok(s) => s,\n    Err(e) if e.to_string().contains(\"required` field should be an array\") => {\n        eprintln!(\"convert `required` to a JSON array of property names\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Remember JSON Schema `required` is an array at the object level, not per-property flags","When converting from OpenAPI, gather per-property required:true names into one array"],"tags":["json-schema","schema-validation","type-mismatch","windmill"],"backgroundTag":"invalid-json-schema","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"}