conductor-oss/conductor · error · UnsupportedSchemaException
{location}: uses unsupported JSON Schema keyword '{key}' at
Error message
{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}. What it means
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.
Source
Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/util/SchemaSubsetValidator.java:131
* Walk {@code schema} recursively, throwing {@link UnsupportedSchemaException} on the first
* unsupported keyword encountered. {@code location} is a human-readable label (e.g. "tool
* 'write_file' inputSchema") prepended to the error message.
*
* <p>A {@code null} or non-Map schema is treated as "no schema" — the runtime path handles it
* the same way (early-return without validation), so accept it here too.
*/
public static void validate(Map<String, Object> schema, String location) {
if (schema == null || schema.isEmpty()) return;
validateInternal(schema, location, "");
}
@SuppressWarnings("unchecked")
private static void validateInternal(Map<String, Object> schema, String location, String path) {
for (Map.Entry<String, Object> e : schema.entrySet()) {
String key = e.getKey();
if (SUPPORTED.contains(key)) continue;
if (KNOWN_UNSUPPORTED.contains(key)) {
throw new UnsupportedSchemaException(
location
+ ": uses unsupported JSON Schema keyword '"
+ key
+ "' at "
+ (path.isEmpty() ? "<root>" : 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: "
+ String.join(", ", SUPPORTED)
+ ".");
}
// Unknown keyword — not in either set. Could be a typo, could be
// a custom extension. Either way, ambiguous behaviour at runtime:
// reject loudly.
throw new UnsupportedSchemaException(
location
+ ": unknown JSON Schema keyword '"View on GitHub (pinned to cf7c3e4a8a)
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.
Example fix
// before
{
"allOf": [
{"type": "object"},
{"required": ["email"]}
],
"properties": {"email": {"type": "string", "format": "email"}}
}
// after (subset only)
{
"type": "object",
"required": ["email"],
"properties": {"email": {"type": "string", "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"}}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate a schema against the runtime subset *before* publishing the tool.
try {
SchemaSubsetValidator.validate(schemaMap, "tool/my-tool");
} catch (UnsupportedSchemaException e) {
throw new IllegalArgumentException(e.getMessage(), e);
} Type guard
boolean isSubsetSchema(Map<String,Object> schema) {
try { SchemaSubsetValidator.validate(schema, "precheck"); return true; }
catch (UnsupportedSchemaException e) { return false; }
} Try / catch
try {
SchemaSubsetValidator.validate(schema, location);
} catch (UnsupportedSchemaException e) {
return badRequest(e.getMessage()); // tell the author which keyword at which path
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- {location}: unknown JSON Schema keyword '{key}' at {path}. A
- ${usx.message}
- null condition
- condition exceeds 1024 characters
- Output does not Confirm to the schema. errors: %s
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/2e52e3b2f6bf9778.
Report an issue: GitHub.