{"record":{"id":"2e52e3b2f6bf9778","repo":"conductor-oss/conductor","slug":"location-uses-unsupported-json-schema-keyword","errorCode":null,"errorMessage":"{location}: uses unsupported JSON Schema keyword '{key}' at {path}. The PAC runtime validator implements a Draft-07 subset; keywords like $ref/allOf/oneOf/format would silently pass at runtime, producing permissive validation. Restrict the schema to: {SUPPORTED}.","messagePattern":"(.+?): uses unsupported JSON Schema keyword '(.+?)' at (.+?)\\. The PAC runtime validator implements a Draft-07 subset; keywords like \\$ref/allOf/oneOf/format would silently pass at runtime, producing permissive validation\\. Restrict the schema to: (.+?)\\.","errorType":"validation","errorClass":"UnsupportedSchemaException","httpStatus":null,"severity":"error","filePath":"agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/util/SchemaSubsetValidator.java","lineNumber":131,"sourceCode":"     * Walk {@code schema} recursively, throwing {@link UnsupportedSchemaException} on the first\n     * unsupported keyword encountered. {@code location} is a human-readable label (e.g. \"tool\n     * 'write_file' inputSchema\") prepended to the error message.\n     *\n     * <p>A {@code null} or non-Map schema is treated as \"no schema\" — the runtime path handles it\n     * the same way (early-return without validation), so accept it here too.\n     */\n    public static void validate(Map<String, Object> schema, String location) {\n        if (schema == null || schema.isEmpty()) return;\n        validateInternal(schema, location, \"\");\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private static void validateInternal(Map<String, Object> schema, String location, String path) {\n        for (Map.Entry<String, Object> e : schema.entrySet()) {\n            String key = e.getKey();\n            if (SUPPORTED.contains(key)) continue;\n            if (KNOWN_UNSUPPORTED.contains(key)) {\n                throw new UnsupportedSchemaException(\n                        location\n                                + \": uses unsupported JSON Schema keyword '\"\n                                + key\n                                + \"' at \"\n                                + (path.isEmpty() ? \"<root>\" : path)\n                                + \". The PAC runtime validator implements a Draft-07 subset; \"\n                                + \"keywords like $ref/allOf/oneOf/format would silently pass at \"\n                                + \"runtime, producing permissive validation. Restrict the schema \"\n                                + \"to: \"\n                                + String.join(\", \", SUPPORTED)\n                                + \".\");\n            }\n            // Unknown keyword — not in either set. Could be a typo, could be\n            // a custom extension. Either way, ambiguous behaviour at runtime:\n            // reject loudly.\n            throw new UnsupportedSchemaException(\n                    location\n                            + \": unknown JSON Schema keyword '\"","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/util/SchemaSubsetValidator.java#L113-L149","documentation":"SchemaSubsetValidator.validate throws UnsupportedSchemaException when a JSON Schema uses a keyword from the KNOWN_UNSUPPORTED set ($ref, $defs, definitions, allOf, anyOf, oneOf, not, if/then/else, dependencies, format, const, multipleOf, exclusiveMinimum/Maximum, uniqueItems, contains, patternProperties, contentEncoding/MediaType/Schema, readOnly/writeOnly, etc.). The runtime inline validator (JavaScriptBuilder.schemaValidatorScript) implements only a Draft-07 subset; using an unsupported keyword would silently pass at runtime, so this check turns that into a loud compile-time rejection.","triggerScenarios":"Authoring a tool's input schema with `$ref`/`$defs` for reuse, `allOf`/`oneOf` for composition, or `format: email` for hinting. validate() recurses, hits the keyword in KNOWN_UNSUPPORTED, and throws with the location and JSON path.","commonSituations":"Author copy-pasted a full Draft-07 schema from another tool; used `$ref` to keep schemas DRY; added `format` expecting email/uri validation at runtime.","solutions":["Inline any `$ref`/`$defs` so the schema is fully flattened into `properties`.","Replace `allOf`/`oneOf`/`anyOf` with explicit per-field constraints the subset validator supports (type, enum, pattern, min/maxLength, min/maximum, min/maxItems, required).","Remove `format` — validate email/uri/etc. in your handler instead of via JSON Schema.","Drop `const`/`default`/`examples`-adjacent unsupported keywords and enforce in code."],"exampleFix":"// before\n{\n  \"allOf\": [\n    {\"type\": \"object\"},\n    {\"required\": [\"email\"]}\n  ],\n  \"properties\": {\"email\": {\"type\": \"string\", \"format\": \"email\"}}\n}\n// after (subset only)\n{\n  \"type\": \"object\",\n  \"required\": [\"email\"],\n  \"properties\": {\"email\": {\"type\": \"string\", \"pattern\": \"^[^@\\\\s]+@[^@\\\\s]+\\\\.[^@\\\\s]+$\"}}\n}","handlingStrategy":"validation","validationCode":"// Validate a schema against the runtime subset *before* publishing the tool.\ntry {\n    SchemaSubsetValidator.validate(schemaMap, \"tool/my-tool\");\n} catch (UnsupportedSchemaException e) {\n    throw new IllegalArgumentException(e.getMessage(), e);\n}","typeGuard":"boolean isSubsetSchema(Map<String,Object> schema) {\n    try { SchemaSubsetValidator.validate(schema, \"precheck\"); return true; }\n    catch (UnsupportedSchemaException e) { return false; }\n}","tryCatchPattern":"try {\n    SchemaSubsetValidator.validate(schema, location);\n} catch (UnsupportedSchemaException e) {\n    return badRequest(e.getMessage()); // tell the author which keyword at which path\n}","preventionTips":["Restrict schemas to the SUPPORTED keyword list (type, properties, required, items, enum, min/maxLength, pattern, min/maximum, min/maxItems, additionalProperties, plus doc-only title/description/examples/default/$schema/$id).","Inline $ref/$defs; do not use composition keywords.","Validate tool schemas in CI with SchemaSubsetValidator."],"tags":["agentspan","json-schema","validation","schema-subset"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}