Skip to content

Report an unresolvable $ref instead of passing silently - #944

Open
Amoifr wants to merge 1 commit into
jsonrainbow:mainfrom
Amoifr:fix-916-unresolvable-ref
Open

Report an unresolvable $ref instead of passing silently#944
Amoifr wants to merge 1 commit into
jsonrainbow:mainfrom
Amoifr:fix-916-unresolvable-ref

Conversation

@Amoifr

@Amoifr Amoifr commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Closes #916.

This takes option 1 from the issue, a validation error, and there is an argument for it beyond it being the least disruptive: CHECK_MODE_STRICT is currently more permissive than the default mode. Same schema, same data, on main:

default mode        : UnresolvableJsonPointerException thrown
CHECK_MODE_STRICT   : isValid = true, 0 errors

The legacy path already refuses to let a broken $ref through; it is only the draft-specific constraints that swallow it. So this is not just a missing feature, it is the strict mode being laxer than the mode it is supposed to tighten. After the change, strict mode reports one error and the default mode is untouched.

On the error constant

The issue suggests MISSING_ERROR or a new one. MISSING_ERROR is not available: its message is commented out in ConstraintError with Used for tests; this error is deliberately commented out, so it is reserved. This adds UNRESOLVABLE_REF with the message The $ref "%s" could not be resolved, which also names the pointer that failed rather than leaving the reader to find it.

On the offline case

The issue rightly raises unreachable remote schemas. Nothing changes there for anyone on the default mode, which already throws. For strict mode, a remote $ref that cannot be fetched now produces a validation error rather than a silent pass, which I think is the honest answer: the validator cannot claim a document conforms to a schema it never read. Option 3, gating on CHECK_MODE_EXCEPTIONS, remains available on top of this if you would rather make it configurable.

Verification

Two tests per draft: an unresolvable $ref is reported with the new constraint name, and a resolvable one still validates. Each fails without the change.

Full suite green at 3166 tests, including the official JSON-Schema-Test-Suite, which is what I would have expected to break had the previous behaviour been load-bearing. PHPStan clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RefConstraint silently passes validation when $ref cannot be resolved

2 participants