ajv icon indicating copy to clipboard operation
ajv copied to clipboard

updating `it.baseId` when using `$ref` with hash fragment

Open jboavida opened this issue 7 years ago • 4 comments

What version of Ajv you are you using?

4.11.8 and 5.1.5.

What problem do you want to solve?

In some cases, the base id is not updated when going inside a $ref. For example:

var ajv = require('ajv')({ v5: true });
ajv.addKeyword('custom', { 
  compile: function (a, b, it) {
    console.log(it.baseId);
    return function () {};
  },
  valid: true
});
ajv.addSchema([
  { id: 'a', properties: { a: { $ref: 'b#/definitions/b' } } },
  { id: 'b', definitions: { b: { custom: 'keyword' } } }
]);
ajv.validate('a', { a: 1 });
ajv.validate('b#/definitions/b',1);

reveals the custom keyword “thinks” the base id is still "a" when invoked from "a", but is "b" when invoked from "b#/definitions/b".

It seems this happens exactly when the $ref'ed schema doesn't have an explicit id set in the schema itself (in this example, the id is set only at the "b" level, not at "b#/definitions/b").

However, nested $refs are not affected by this problem at all: they keep resolving to the correct schema. It's only when we nest a custom keyword inside (any number of nested) $refs that it's possible to get a mismatch.

What do you think is the correct solution to problem?

It would be nice to have the base id even in these cases. However, I'm not even sure whether this is a bug report or a feature request, as the spec doesn't address this case directly. Still, it would be nice to have the same base id independently of how the schema is invoked.

There's a closed issue that apparently involved a similar case, so maybe this one is a leftover corner case?

Will you be able to implement it?

I was not (yet) able to figure how/where the change would be made.

jboavida avatar Jun 08 '17 22:06 jboavida

@jboavida interesting. Btw it works correctly with option {inlineRefs: false}: https://runkit.com/esp/5939da4956ebfd0012d13943

epoberezkin avatar Jun 08 '17 23:06 epoberezkin

Very neat. And it explains why the nesting of the custom keyword was working in similar scenarios (the keyword does a dynamic $ref, which really is sort of a non-inline $ref).

Btw: thanks for your extremely quick answers. It's quite impressive how you seem to always get to everyone's questions super-fast.

jboavida avatar Jun 09 '17 10:06 jboavida

I'm running into this issue as well. I see that it's not a high priority to fix, so I thought I would mention why it matters to me.

I'd like to include more context, vis-a-vis a justification for why a schema rule exists, on my validation errors.

That context would be great to put inside the actual schema, for example in an x-justification extension, that provides a more editorial error message for when a particular schema portion detects invalid data.

I was hoping to use the schemaPath to grab the part of the schema that failed, and check if there was any x-justification property on it, to use for error output.

jlacivita avatar Aug 09 '22 18:08 jlacivita