Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolution of relative $ref with fragment #666

Closed
cschramm opened this issue Dec 31, 2024 · 5 comments · Fixed by #674
Closed

Resolution of relative $ref with fragment #666

cschramm opened this issue Dec 31, 2024 · 5 comments · Fixed by #674

Comments

@cschramm
Copy link

cschramm commented Dec 31, 2024

Follow up to #432 (comment) (Sorry, it was not #640 and unfortunately 0.28.1 / #665 does not fix it)

A relative $ref with a fragment like other.json#/$defs/obj1 fails to resolve.

Due to 4b34b75#diff-fd99d42493bf63977b4e2c0b1a10fdcef8528f837daee1a504d68d0b24186cf5L455-R475, the retriever gets passed json-schema:///other.json instead of other.json resolved against the $id of the containing schema.

The if branch added in that change might have just been a workaround for references starting with a fragment that #665 now handled in resolve_against so that it's probably obsolete. It seems harmful for references not starting with a fragment, but containing one. I do not really understand why DEFAULT_ROOT_URI would ever be used over a present base.

@Stranger6667
Copy link
Owner

Could you, please, share an example of such a schema? It would help me a lot with fixing the issue

@cschramm
Copy link
Author

cschramm commented Jan 2, 2025

Well, trying to prepare a minimal example got me completely confused now. The issue seems to depend on some execution order or something and is not as general as expected.

Having a /tmp/schemas/one.json with

{
  "$defs": {
    "obj": {
      "$ref": "other.json#/$defs/obj"
    }
  }
}

and running

jsonschema::validator_for(&json!({
    "$id": "file:///tmp/schemas/root.json",
    "$ref": "one.json#/$defs/obj"
}))
.unwrap();

There seems to be a 50:50 chance to get

ValidationError { instance: Null, kind: Referencing(Unretrievable { uri: "json-schema:///other.json", source: "Unknown scheme json-schema" }), instance_path: Location(""), schema_path: Location("") }

or

ValidationError { instance: Null, kind: Referencing(Unretrievable { uri: "file:///tmp/schemas/other.json", source: Os { code: 2, kind: NotFound, message: "No such file or directory" } }), instance_path: Location(""), schema_path: Location("") }

(as I do not have that file)

@cschramm
Copy link
Author

cschramm commented Jan 3, 2025

Ok, forget the confusion. In any case external at

for uri in external.drain() {
contains both json-schema:///other.json#/$defs/obj and file:///tmp/schemas/other.json#/$defs/obj. The error just depends on their order and when I add a /tmp/schemas/other.json with e.g.

{
  "$defs": {
    "obj": {
      "type": "number"
    }
  }
}

I always get the Unknown scheme json-schema error.

@Stranger6667
Copy link
Owner

Stranger6667 commented Jan 22, 2025

Hi @cschramm

Sorry for the delay! The issue should be fixed in 0.28.2 - relative paths are resolved against the existing $id now and this code does not fail anymore:

jsonschema::validator_for(&json!({
    "$id": "file:///tmp/schemas/root.json",
    "$ref": "one.json#/$defs/obj"
}))
.unwrap();

Also, see the test case

Please, let me know if it does not solve the issue for you (I believe it should)

@cschramm
Copy link
Author

Awesome, thanks! I can confirm that it works well for my cases. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants