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

$id doesn't alter resolution scope for { "$ref": "#" } #815

Closed
jdesrosiers opened this issue Jul 4, 2018 · 8 comments
Closed

$id doesn't alter resolution scope for { "$ref": "#" } #815

jdesrosiers opened this issue Jul 4, 2018 · 8 comments
Milestone

Comments

@jdesrosiers
Copy link

jdesrosiers commented Jul 4, 2018

While helping someone write a JSON Schema that involves recursion, I noticed that ajv doesn't correctly resolve { "$ref": "#" } when an $id is altering the resolution scope.

What version of Ajv are you using? Does the issue happen if you use the latest version?

I was using http://jsonschemalint.com which uses ajv, but I don't know exactly what version is used. I observed the same problems with draft-04 and draft-06.

JSON Schema

Here's an example I put together to illustrate the issue.

{
  "allOf": [
    {
      "$id": "http://example.com/schema/person",
      "title": "Person",
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "spouse": { "$ref": "#" },
        "children": {
          "type": "array",
          "items": { "$ref": "#" }
        }
      },
      "required": ["name"]
    }
  ],
  "properties": {
    "root": { "const": true }
  },
  "required": ["root"]
}

Sample data

{
  "root": true,
  "name": "John",
  "spouse": { "name": "Jane" },
  "children": [
    { "name": "James" },
    { "name": "Jessica" }
  ]
}

Validation result, data AFTER validation, error messages

It says that the /spouse schema and the /children schemas require a "root" property.

What results did you expect?

I expect the "root" property to only be required at the top level. The $id keyword should change the resolution scope of { "$ref": "#" } so it refers to /allOf/0 rather than the top level of the document. Using { "$ref": "" } instead does work as expected.

Are you going to resolve the issue?

It's not likely that I will get to this any time soon. I just wanted to bring this to your attention.

@epoberezkin
Copy link
Member

Thank you, I think I know why it is the case. Workaround is indeed easy but it should work.

@KurtPreston
Copy link

KurtPreston commented Feb 26, 2019

@epoberezkin Heads up, looks like this is still an issue in the latest ajv (v6.9.2). The mentioned workaround no longer seems to work either.

KurtPreston pushed a commit to KurtPreston/ajv that referenced this issue Feb 26, 2019
@KurtPreston
Copy link

@epoberezkin Heads up, I wrote a spec to reproduce the issue. I took a crack at solving it, but was having issues wrapping my head around how resolve.js works. If it's at all useful, here's the spec:
https://github.com/epoberezkin/ajv/compare/master...KurtPreston:issue815_idSetsRefScope?expand=1

@epoberezkin
Copy link
Member

It’s indeed an existing limitation.

@epoberezkin
Copy link
Member

Resolve.js is indeed a bit of a puzzle, but this issue is in ref.jst.
I tried fixing it at some point but it turned out to be more complex.
Given that it’s a relatively narrow use case and it normally happens only if you try to bundle multiple schemas into a single file (which I believe is not something that should be done, better to keep them separately), I never had fixing it as a high priority.
Are you trying to compile a bundled schema? Or what’s the use case?

@KurtPreston
Copy link

We have two circumstances where we're running into the issue:

  1. We have several interrelated JSONSchema files. We currently resolve references as a build step during compilation and output the combined schema in our build directory so that at runtime, the compiled JSONSchema have complete definitions.
  2. At runtime, we sometimes dynamically generate JSONSchema based upon UI state. These dynamically generated JSONSchemas frequently combine several other schemas. These schemas only exist in memory—they are never saved to disk or served via URL.

We've also tried using named anchors ("$id": "#myName") which is supported by ajv, but the feature doesn't seem globally supported yet.

@epoberezkin epoberezkin added this to the 7.0.0 milestone Sep 15, 2020
epoberezkin added a commit that referenced this issue Dec 13, 2020
…eck that anchor is present (no support yet for $id changing resolution scope, similar to #815)
@epoberezkin epoberezkin modified the milestones: 7.0.0, v9+ Feb 10, 2021
@epoberezkin epoberezkin modified the milestones: v9+, 8.0.0 Mar 17, 2021
epoberezkin added a commit that referenced this issue Mar 17, 2021
epoberezkin added a commit that referenced this issue Mar 17, 2021
…tsRefScope

$id doesn't change Base URI $ref "#" (#815)
@epoberezkin
Copy link
Member

fixed in v8

@epoberezkin epoberezkin mentioned this issue Mar 17, 2021
Merged
11 tasks
@epoberezkin
Copy link
Member

v8 now released: https://ajv.js.org/v6-to-v8-migration.html

andriyl pushed a commit to Redocly/ajv that referenced this issue Jun 16, 2021
…eck that anchor is present (no support yet for $id changing resolution scope, similar to ajv-validator#815)
andriyl pushed a commit to Redocly/ajv that referenced this issue Jun 16, 2021
andriyl pushed a commit to Redocly/ajv that referenced this issue Jun 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants
@KurtPreston @jdesrosiers @epoberezkin and others