Skip to content

SchemaRegistry::getUnifiedSchema() emits invalid empty anyOf when no providers are registered #3

Description

@eluhr

Summary

SchemaRegistry::getUnifiedSchema() emits an invalid JSON Schema when no providers are registered: {"anyOf": []}. Per the JSON Schema spec anyOf MUST be a non-empty array, so any consumer that hands this schema to a validator (e.g. opis/json-schema) crashes at schema-parse time with anyOf must have at least one element.

  • dmstr/openapi-json-schema-bundle: 0.3.0
  • PHP 8.4, opis/json-schema 2.x

Where

src/Service/SchemaRegistry.php, generateUnifiedSchema():

if (empty($this->providers)) {
    $this->logger->warning('No schema providers registered, returning empty anyOf schema');
    return [
        '$schema' => 'https://json-schema.org/draft-07/schema#',
        'description' => 'No schemas available',
        'anyOf' => []            // <-- invalid: anyOf must be non-empty
    ];
}

Impact

Any code path that validates data against the unified schema throws instead of failing gracefully. Concretely this surfaces in dmstr/api-configuration-bundle as an HTTP 500 on every ApiConfiguration write when no SchemaProviderInterface is registered — see dmstr/api-configuration-bundle#5 for the full stack trace. But the invalid output originates here and is independent of that consumer.

Expected

getUnifiedSchema() should always return a valid, parseable schema. When there are no providers, emit a schema with well-defined semantics instead of an illegal anyOf: []. Reasonable choices:

  • false — the JSON Schema "reject everything" value (any instance is invalid → callers get a clean validation failure, not a parse crash), or
  • ['not' => new \stdClass()] — equivalent "matches nothing" using an object schema, if a boolean schema is awkward for downstream code, or
  • a documented sentinel the decorators/validators can special-case (e.g. skip validation entirely when empty).

Whatever the choice, the contract should be "the returned schema always parses".

Steps to reproduce

  1. Register the bundle with zero SchemaProviderInterface services.
  2. Call SchemaRegistry::getUnifiedSchema() and validate any value against it with opis/json-schema.
  3. anyOf must have at least one element thrown during schema parsing.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions