conductor-oss/conductor · error · IllegalStateException

${usx.message}

Error message

${usx.message}

What it means

Thrown as IllegalStateException wrapping a SchemaSubsetValidator.UnsupportedSchemaException. The validator checks that a tool's inputSchema only uses JSON Schema keywords the runtime INLINE validator actually handles (a Draft-07 subset). Unsupported keywords like $ref, allOf, oneOf, format, etc. would silently pass at runtime, producing permissive validation. The message is forwarded verbatim from the validator.

Source

Thrown at agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/compiler/MultiAgentCompiler.java:2619

        List<Map<String, Object>> parentToolsAsMaps = new ArrayList<>();
        for (ToolConfig t : parentTools) {
            // /dg #1: reject schemas using JSON-Schema features the runtime
            // INLINE validator silently ignores ($ref, allOf, anyOf, oneOf,
            // format, if/then/else, etc.). Without this check users got
            // permissive runtime validation — the schema appears to declare
            // constraints but the validator never fires them. Fail at
            // agent-compile time with the exact offending keyword + path.
            if (t.getInputSchema() != null) {
                try {
                    SchemaSubsetValidator.validate(
                            t.getInputSchema(),
                            "PLAN_EXECUTE '"
                                    + config.getName()
                                    + "': tool '"
                                    + t.getName()
                                    + "' inputSchema");
                } catch (SchemaSubsetValidator.UnsupportedSchemaException usx) {
                    throw new IllegalStateException(usx.getMessage(), usx);
                }
            }
            try {
                @SuppressWarnings("unchecked")
                Map<String, Object> m = MAPPER.convertValue(t, Map.class);
                parentToolsAsMaps.add(m);
            } catch (Exception e) {
                // /dg #7: fail-closed on ALL serialization failures, not just
                // guardrailed ones. Previously a non-guardrailed tool was
                // silently dropped from parentToolsByName with only a WARN,
                // which meant ``knownToolNames`` still allowed the tool but
                // PAC had no schema / inputSchema / guardrail context — a
                // generate-op output landed in a bare SIMPLE with no
                // validation. Treat the divergence as a compile error so the
                // user fixes the ToolConfig (typically a non-Jackson-friendly
                // value in inputSchema or config) instead of shipping a
                // half-configured tool. Guardrailed tools get the longer
                // diagnostic since the failure mode there is more dangerous.

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Inline all $ref references — replace $ref pointers with their resolved schema objects directly.
  2. Replace format constraints (e.g., 'format': 'email') with explicit pattern regex or remove them.
  3. Flatten allOf/anyOf/oneOf compositions into a single object schema.
  4. Replace const with enum: [value].
  5. Remove patternProperties, readOnly, writeOnly, and other non-supported keywords.

Example fix

// before: inputSchema with $ref and format
{
  "type": "object",
  "properties": {
    "email": {"type": "string", "format": "email"},
    "user": {"$ref": "#/$defs/User"}
  },
  "$defs": {"User": {"type": "object", "properties": {"name": {"type": "string"}}}}
}
// after: inlined, format removed, $ref resolved
{
  "type": "object",
  "properties": {
    "email": {"type": "string", "pattern": "^[^@]+@[^@]+\\.[^@]+$"},
    "user": {"type": "object", "properties": {"name": {"type": "string"}}}
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate all tool input schemas before compiling
private static final Set<String> SUPPORTED = new LinkedHashSet<>(Arrays.asList(
    "type", "properties", "required", "additionalProperties", "items",
    "enum", "minLength", "maxLength", "pattern", "minimum", "maximum",
    "minItems", "maxItems", "title", "description", "examples",
    "default", "$schema", "$id"));

void preValidateSchemas(List<ToolConfig> tools) {
    for (ToolConfig t : tools) {
        if (t.getInputSchema() != null) {
            SchemaSubsetValidator.validate(t.getInputSchema(),
                "tool '" + t.getName() + "' inputSchema");
        }
    }
}

Try / catch

try {
    SchemaSubsetValidator.validate(tool.getInputSchema(), location);
} catch (SchemaSubsetValidator.UnsupportedSchemaException e) {
    // rewrite the schema to use only supported keywords, then retry
    log.warn("Schema rejected: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: A PLAN_EXECUTE-strategy agent with a tool whose inputSchema (ToolConfig.getInputSchema()) contains an unsupported JSON Schema keyword. The supported set is: type, properties, required, additionalProperties, items, enum, minLength, maxLength, pattern, minimum, maximum, minItems, maxItems, title, description, examples, default, $schema, $id. Keywords like $ref, allOf, anyOf, oneOf, format, const, if/then/else, patternProperties, and others are rejected.

Common situations: Using a JSON Schema generated by Pydantic, FastAPI, or OpenAPI that includes $ref/$defs (very common with Pydantic v2), format constraints (e.g., 'format': 'date-time'), or allOf/anyOf composition. These are valid Draft-07 but the runtime validator ignores them silently, so the compiler rejects them at compile time.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/ad32c2b5921e3fd3. Report an issue: GitHub.