Swagger-ui: v3 - Resolver error - Cannot read property '1' of undefined

Created on 11 Jul 2017  路  16Comments  路  Source: swagger-api/swagger-ui

This error occured when we upgraded to swagger ui 3.x.
We use [email protected].

The issue can be reproduced with the following swagger-spec on Swagger Editor:

# this is an bug report spec
swagger: '2.0'
info:
  title: Swagger UI 3 Bug Report
  description: |
    This will display the following error:

    ## Resolver error

    `Cannot read property '1' of undefined`
  version: 1.0.0
host: localhost
schemes:
  - https
basePath: /v1
produces:
  - application/json
paths:
  /resolver-error:
    get:
      tags:
        - Bug Report
      responses:
        200:
          description: The trouble maker
          schema:
            $ref: '#/definitions/foo-bar'

definitions:
  foo-bar:
    allOf:
      - $ref: '#/definitions/baz'
      - properties:
          data:
            type: array
            items:
              $ref: '#/definitions/foo'

  foo:
    allOf:
      - $ref: '#/definitions/bar'
      - properties:
          foo:
            type: string

  bar:
    properties:
      bar:
        type: string
      foo:
        $ref: '#/definitions/foo'

  baz:
    properties:
      baz:
        type: string
P2 lock-bot swagger-js bug 3.x

Most helpful comment

I'm happy to report that Swagger UI v3.12.0 (presumably this specific fix: https://github.com/swagger-api/swagger-ui/pull/4273) now correctly resolves two examples above that were previously failing with Resolver error: Cannot read property '<prop>' of undefined (https://github.com/swagger-api/swagger-ui/issues/3366#issuecomment-366096404 and https://github.com/swagger-api/swagger-ui/issues/3366#issuecomment-366565475)

All 16 comments

Yeah, this is due to the circular reference.

This could be related to: #3051

I have the same problem defining a tree structure. It's very disconcerting when the first thing a user sees at http://www.genetrees.org is an obscure error message. Is there a way to suppress the error message?

See the TreeNode definition here

@webron Does your comment above mean that circular references are not allowed?
Is there a way to allowCircular or ignore the error?

Our spec requires the use of a circular reference.

Need to be able to remove error messages. For whatever reason, it might not be something that's easily fixable, or just something that the resolver can't handle correctly.

@stoutfiles if hiding the error is all want, try a custom css:

.errors-wrapper {
    display: none !IMPORTANT;
}

@heldersepu, good thinking!

@stoutfiles, alternatively, if modifying JS is more your speed, here are a pair of Swagger-UI plugins that will hide resolver errors or hide all errors:

  // hide errors that come from the resolver
  const HideResolverErrorsPlugin = () => {
    return {
      statePlugins: {
        err: {
          wrapSelectors: {
            allErrors: (ori) => () => {
              return ori().filter(err => err.get("source") !== "resolver")
            }
          }
        }
      }
    }
  }

  // hide the entire Errors container
  const HideAllErrorsPlugin = () => {
    return {
      wrapComponents: {
        errors: () => () => null
      }
    }
  }

We added the suggested plugin above, and it gets around the immediate problem. I'd like to see something in swagger-js that will not cause an error for this particular case in the first place.

I've got a similar problem with

Resolver error: Cannot read property 'items' of undefined

Note: my problem was solved with Swagger UI 3.11.0, example now works fine.

One of our users has hit this issue, and interestingly it only seems to occur if the object with the circular reference (Item) is itself referenced by another object (List).

To explain, here's an example that causes a Resolver error: Cannot read property 'children' of undefined:

{
  "swagger": "2.0",
  "info": {
    "title": "Test API"
  },
  "basePath": "/",
  "paths": {
    "/test": {
      "get": {
        "responses": {
          "200": {
            "schema": {
              "$ref": "#/definitions/List"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "List": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/Item"
      }
    },
    "Item": {
      "type": "object",
      "properties": {
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Item"
          }
        }
      }
    }
  }
}

And here is a functionally equivalent version, that doesn't exhibit the error.

The only difference is simply that the GET /test "200 OK" response schema directly references an array of Item objects, instead of via the interim List definition:

{
  "swagger": "2.0",
  "info": {
    "title": "Test API"
  },
  "basePath": "/",
  "paths": {
    "/test": {
      "get": {
        "responses": {
          "200": {
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Item"
              }
            }
          }
        }
      }
    }
  },
  "definitions": {
    "Item": {
      "type": "object",
      "properties": {
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Item"
          }
        }
      }
    }
  }
}

Actually, it may not be the circular reference at all. I suspect it is something to do with the number of levels being traversed when resolving.

Here is another reduced test case that also gets a Resolver error: Cannot read property 'items' of undefined, but this time there is no circular reference.

open_api_customer_support_-_test_space_-_confluence

In total, there are 4 levels to get down to the leaf Item. Collapsing any one of these (down to 3 levels) seems to fix the problem, e.g.

  1. Remove #/parameters/list, and inline the parameter definition into the PUT /list operation, or
  2. Remove #/definitions/Items, and inline the array definition into #/definitions/List
  3. Remove #/definitions/Item, and inline the the object definition into the array items in #/definitions/Items
{
  "swagger": "2.0",
  "paths": {
    "/list": {
      "put": {
        "parameters": [
          {
            "$ref": "#/parameters/list"
          }
        ]
      }
    }
  },
  "parameters": {
    "list": {
      "name": "list",
      "in": "body",
      "schema": {
        "$ref": "#/definitions/List"
      }
    }
  },
  "definitions": {
    "List": {
      "type": "object",
      "properties": {
        "items": {
          "$ref": "#/definitions/Items"
        }
      }
    },
    "Items": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/Item"
      }
    },
    "Item": {
      "type": "object",
      "properties": {
        "itemId": {
          "type": "string"
        }
      }
    }
  }
}

When working with a similar example I found that removing forward references in the definitions removed the error. ie declare 'Item' then 'Items' then 'List'. Same definitions.. just change in order.

Obviously this is not a real fix as you want to order your object definitions in a more accessible manner but perhaps it might assist in locating the issue in the resolver code? Perhaps the issue is the number of forward references, as @scottohara points out, collapsing references into inline definitions also removes the error message.

Here is the above definition from @scottohara reordered, and not showing the unexpected errror.

{
  "swagger": "2.0",
  "info": {
    "version": "0",
    "title": "No forward references",
    "description": "sample"
  },
  "paths": {
    "/list": {
      "put": {
        "parameters": [
          {
            "$ref": "#/parameters/list"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/responses/OK"
          }
        }
      }
    }
  },
  "parameters": {
    "list": {
      "name": "list",
      "in": "body",
      "schema": {
        "$ref": "#/definitions/List"
      }
    }
  },
  "responses": {
    "OK": {
      "description": "200 OK"
    }
  },
  "definitions": {
    "Item": {
      "type": "object",
      "properties": {
        "itemId": {
          "type": "string"
        }
      }
    },
    "Items": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/Item"
      }
    },
    "List": {
      "type": "object",
      "properties": {
        "items": {
          "$ref": "#/definitions/Items"
        }
      }
    }
  }
}

no forward

This PR (https://github.com/swagger-api/swagger-js/pull/1243) seems to also confirm that order of references can workaround the issue (definitions before paths; and within definitions, declaration before use).

I'm happy to report that Swagger UI v3.12.0 (presumably this specific fix: https://github.com/swagger-api/swagger-ui/pull/4273) now correctly resolves two examples above that were previously failing with Resolver error: Cannot read property '<prop>' of undefined (https://github.com/swagger-api/swagger-ui/issues/3366#issuecomment-366096404 and https://github.com/swagger-api/swagger-ui/issues/3366#issuecomment-366565475)

Closing as resolved.

Was this page helpful?
0 / 5 - 0 ratings