Skip to content

Fails to resolve correct path/filename for extended $ref #200

Closed
@daniellubovich

Description

@daniellubovich

I recently ran into an issue testing some of my more complex schema documents where combination schema $refs cannot be resolved properly if they are part of an "extended" $ref. It is a little hard to explain the case, but I think I have found a simple enough schema that causes the problem to occur.

// base.json
{
  "type": "object",
  "properties": {
    "some_value": { "$ref": "defs.json#/definitions/astring" }
  }
}

//

{
  "definitions": {
    "astring": {
      "description": "astring",
      "$ref": "defs2.json#/definitions/bstring"
    }
  }
}


// defs2.json
{
  "definitions": {
    "bstring": {
      "oneOf": [
        {
          "$ref": "#/definitions/cstring"
        },
        {
          "$ref": "#/definitions/dstring"
        }
      ]
    },
    "cstring": {
      "type": "string"
    },
    "dstring": {
      "type": "number"
    }
  }
}

The error that I see when trying to resolve this looks like:
Error while processing route: dynamic-form Token "cstring" does not exist. MissingPointerError: Token "cstring" does not exist.

This only seems to happen when the intermediate schema object is an "extended" ref. For example, if we remove the description from astring then we are able to dereference without issue. From doing some debugging it looks to me like our issue is that when resolving cstring, the path we resolve is defs.json#/definitions/cstring instead of looking in defs2.json. I think this is because when we resolve extended $refs, we explicitly do not update the pointer's path.

For reference:

if ($Ref.isExtended$Ref(pointer.value)) {
// This JSON reference "extends" the resolved value, rather than simply pointing to it.
// So the resolved path does NOT change. Just the value does.
pointer.value = $Ref.dereference(pointer.value, resolved.value);
return false;
}

I would like to propose a fix, but feel ill-equipped to do so without some guidance. It does seem like updating the path in the above code fixes my specific issue, but clearly that decision was made for a reason so I'd rather not step on any toes without understanding the intent. Any thoughts would be greatly appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions