Skip to content

Semantic Error at OASv3 for 'MessageExcluding[id]': #3698

@remkohdev

Description

@remkohdev

A Loopback4 generated application (https://github.com/remkohdev/guestbook101/blob/master/Lab0/README_w_lb4_cli.md) provides an OAS v3 that gives me the following semantic error in Swagger editor, which I assume uses Swagger Validator. I validated the Swagger in Swagger Editor after getting issues in API Connect (I now realize I should not be using v3 at all, when using API Connect, which means I cannot use Appsody, LB4 CLI, that's another story)

If I go to editor.swagger.io and import my OAS in Loopback4 (http://169.63.218.104:32145/openapi.yaml), the validator throws a semantic error 👍

Semantic Error at paths./messages.post.requestBody.content.application/json.schema.$ref
$ref values must be RFC3986-compliant percent-encoded URIs
Jump to line 190

Line 190 refers to $ref: '#/components/schemas/MessageExcluding[id]' that points to

     'MessageExcluding[id]':
     title: 'MessageExcluding[id]'
     not:
       anyOf:
         - required:
             - id
     properties:

I can resolve the error in Swagger Editor by URLEncoding the square brackets as follows: $ref: '#/components/schemas/MessageExcluding%5Bid%5D'

Does this mean the Loopback 4 application wrongly generates the ref? or is the error in the swagger validator in the swagger editor?

{
  "openapi": "3.0.0",
  "info": {
    "title": "LoopBack Application",
    "version": "1.0.0"
  },
  "paths": {
    "/addresses/{id}/contact": {
      "get": {
        "x-controller-name": "AddressContactController",
        "x-operation-name": "getContact",
        "tags": [
          "AddressContactController"
        ],
        "responses": {
          "200": {
            "description": "Contact belonging to Address",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Contact"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "schema": {
              "type": "number"
            },
            "required": true
          }
        ],
        "operationId": "AddressContactController.getContact"
      }
    },
    "/contacts/{id}/person": {
      "get": {
        "x-controller-name": "ContactPersonController",
        "x-operation-name": "getPerson",
        "tags": [
          "ContactPersonController"
        ],
        "responses": {
          "200": {
            "description": "Person belonging to Contact",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Person"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "schema": {
              "type": "number"
            },
            "required": true
          }
        ],
        "operationId": "ContactPersonController.getPerson"
      }
    },
    "/messages/count": {
      "get": {
        "x-controller-name": "MessagesController",
        "x-operation-name": "count",
        "tags": [
          "MessagesController"
        ],
        "responses": {
          "200": {
            "description": "Message model count",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "where",
            "in": "query",
            "style": "deepObject",
            "explode": true,
            "schema": {
              "type": "object"
            }
          }
        ],
        "operationId": "MessagesController.count"
      }
    },
    "/messages/{id}/person": {
      "get": {
        "x-controller-name": "MessagePersonController",
        "x-operation-name": "getPerson",
        "tags": [
          "MessagePersonController"
        ],
        "responses": {
          "200": {
            "description": "Person belonging to Message",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Person"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "schema": {
              "type": "number"
            },
            "required": true
          }
        ],
        "operationId": "MessagePersonController.getPerson"
      }
    },
    "/messages/{id}": {
      "put": {
        "x-controller-name": "MessagesController",
        "x-operation-name": "replaceById",
        "tags": [
          "MessagesController"
        ],
        "responses": {
          "204": {
            "description": "Message PUT success"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "schema": {
              "type": "number"
            },
            "required": true
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Message"
              }
            }
          },
          "x-parameter-index": 1
        },
        "operationId": "MessagesController.replaceById"
      },
      "patch": {
        "x-controller-name": "MessagesController",
        "x-operation-name": "updateById",
        "tags": [
          "MessagesController"
        ],
        "responses": {
          "204": {
            "description": "Message PATCH success"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "schema": {
              "type": "number"
            },
            "required": true
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessagePartial"
              }
            }
          },
          "x-parameter-index": 1
        },
        "operationId": "MessagesController.updateById"
      },
      "get": {
        "x-controller-name": "MessagesController",
        "x-operation-name": "findById",
        "tags": [
          "MessagesController"
        ],
        "responses": {
          "200": {
            "description": "Message model instance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "schema": {
              "type": "number"
            },
            "required": true
          }
        ],
        "operationId": "MessagesController.findById"
      },
      "delete": {
        "x-controller-name": "MessagesController",
        "x-operation-name": "deleteById",
        "tags": [
          "MessagesController"
        ],
        "responses": {
          "204": {
            "description": "Message DELETE success"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "schema": {
              "type": "number"
            },
            "required": true
          }
        ],
        "operationId": "MessagesController.deleteById"
      }
    },
    "/messages": {
      "post": {
        "x-controller-name": "MessagesController",
        "x-operation-name": "create",
        "tags": [
          "MessagesController"
        ],
        "responses": {
          "200": {
            "description": "Message model instance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Message"
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageExcluding[id]"
              }
            }
          }
        },
        "operationId": "MessagesController.create"
      },
      "patch": {
        "x-controller-name": "MessagesController",
        "x-operation-name": "updateAll",
        "tags": [
          "MessagesController"
        ],
        "responses": {
          "200": {
            "description": "Message PATCH success count",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "where",
            "in": "query",
            "style": "deepObject",
            "explode": true,
            "schema": {
              "type": "object"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessagePartial"
              }
            }
          }
        },
        "operationId": "MessagesController.updateAll"
      },
      "get": {
        "x-controller-name": "MessagesController",
        "x-operation-name": "find",
        "tags": [
          "MessagesController"
        ],
        "responses": {
          "200": {
            "description": "Array of Message model instances",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Message"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "filter",
            "in": "query",
            "style": "deepObject",
            "explode": true,
            "schema": {
              "type": "object",
              "properties": {
                "where": {
                  "type": "object"
                },
                "fields": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "boolean"
                    },
                    "text": {
                      "type": "boolean"
                    },
                    "datecreated": {
                      "type": "boolean"
                    },
                    "personId": {
                      "type": "boolean"
                    }
                  }
                },
                "offset": {
                  "type": "integer",
                  "minimum": 0
                },
                "limit": {
                  "type": "integer",
                  "minimum": 0
                },
                "skip": {
                  "type": "integer",
                  "minimum": 0
                },
                "order": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "include": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "relation": {
                        "type": "string"
                      },
                      "scope": {
                        "properties": {
                          "where": {
                            "type": "object"
                          },
                          "fields": {
                            "type": "object",
                            "properties": {}
                          },
                          "offset": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "limit": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "skip": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "order": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ],
        "operationId": "MessagesController.find"
      }
    },
    "/ping": {
      "get": {
        "x-controller-name": "PingController",
        "x-operation-name": "ping",
        "tags": [
          "PingController"
        ],
        "responses": {
          "200": {
            "description": "Ping Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "greeting": {
                      "type": "string"
                    },
                    "date": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "headers": {
                      "type": "object",
                      "properties": {
                        "Content-Type": {
                          "type": "string"
                        }
                      },
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "PingController.ping"
      }
    }
  },
  "servers": [
    {
      "url": "http://169.63.218.104:32145"
    }
  ],
  "components": {
    "schemas": {
      "Contact": {
        "title": "Contact",
        "properties": {
          "id": {
            "type": "number"
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "personId": {
            "type": "number"
          }
        }
      },
      "Person": {
        "title": "Person",
        "properties": {
          "id": {
            "type": "number"
          },
          "firstname": {
            "type": "string"
          },
          "lastname": {
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        }
      },
      "Message": {
        "title": "Message",
        "properties": {
          "id": {
            "type": "number"
          },
          "text": {
            "type": "string"
          },
          "datecreated": {
            "type": "string",
            "format": "date-time"
          },
          "personId": {
            "type": "number"
          }
        },
        "required": [
          "text"
        ]
      },
      "MessageExcluding[id]": {
        "title": "MessageExcluding[id]",
        "not": {
          "anyOf": [
            {
              "required": [
                "id"
              ]
            }
          ]
        },
        "properties": {
          "text": {
            "type": "string"
          },
          "datecreated": {
            "type": "string",
            "format": "date-time"
          },
          "personId": {
            "type": "number"
          }
        },
        "required": [
          "text"
        ]
      },
      "MessagePartial": {
        "title": "MessagePartial",
        "properties": {
          "id": {
            "type": "number"
          },
          "text": {
            "type": "string"
          },
          "datecreated": {
            "type": "string",
            "format": "date-time"
          },
          "personId": {
            "type": "number"
          }
        }
      }
    }
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions