swagger-ui
swagger-ui copied to clipboard
Path parameter issues: "Required field is not provided" or interpolates to a ','
Q&A
- OS: Windows Sub-system for Linux (WSL): Ubuntu 18.04.3 LTS
$ cat /etc/os-release | head -2
NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"
- Browser: Chrome 79.0.3945.88 & Firefox 68.4.0esr
- Method of installation:
$ npm -v
6.13.4
- Swagger-UI version: 3.24.3
- Swagger/OpenAPI version: OpenAPI 3.0.1
Content & configuration
Example Swagger/OpenAPI definition: Stripped down version of PetStore example in OpenAPI 3.0.1
{
"openapi": "3.0.1",
"info": {
"description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
"version": "2.0.0",
"title": "Swagger Petstore",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"email": "[email protected]"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"servers": [
{
"url": "https://petstore.swagger.io/v2"
}
],
"tags": [
{
"name": "pet",
"description": "Everything about your Pets",
"externalDocs": {
"description": "Find out more",
"url": "http://swagger.io"
}
}
],
"paths": {
"/pet/{petId}": {
"get": {
"tags": [
"pet"
],
"summary": "Find pet by ID",
"description": "Returns a single pet",
"operationId": "getPetById",
"parameters": [
{
"name": "petId",
"in": "path",
"description": "ID of pet to return",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pet"
}
},
"application/xml": {
"schema": {
"$ref": "#/components/schemas/Pet"
}
}
}
},
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Pet not found"
}
}
}
}
},
"components": {
"schemas": {
"Category": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"xml": {
"name": "Category"
}
},
"Pet": {
"type": "object",
"required": [
"name",
"photoUrls"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"category": {
"$ref": "#/components/schemas/Category"
},
"name": {
"type": "string",
"example": "doggie"
},
"photoUrls": {
"type": "array",
"xml": {
"wrapped": true
},
"items": {
"type": "string",
"xml": {
"name": "photoUrl"
}
}
},
"tags": {
"type": "array",
"xml": {
"wrapped": true
},
"items": {
"xml": {
"name": "tag"
},
"$ref": "#/components/schemas/Tag"
}
},
"status": {
"type": "string",
"description": "pet status in the store",
"enum": [
"available",
"pending",
"sold"
]
}
},
"xml": {
"name": "Pet"
}
},
"Tag": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"xml": {
"name": "Tag"
}
}
}
}
}
Swagger-UI configuration options:
SwaggerUI({
docExpansion: 'list',
domNode: document.getElementById(config.swaggerElementID),
spec: swaggerJsonObject,
});
Your query string config: N/A
Describe the bug you're encountering
When the path parameter required
property is set to true
, all input is rejected with error: Required field is not provided
(screenshot 1).
If I set the path parameter required
property to false
, the path parameter interpolates to a ',' (screenshot 2). I've tried defining the path parameter inline as well as in the components section and various other things, but always get the comma.
Example:
Curl
curl -X GET "https://petstore.swagger.io/v2/pet/," -H "accept: */*"
Request
https://petstore.swagger.io/v2/pet/,
Response body
{
"code": 404,
"type": "unknown",
"message": "java.lang.NumberFormatException: For input string: \",\""
}
To reproduce...
Steps to reproduce the behavior:
-
npm run-script start
, which executesreact-scripts start
- Click on 'Try it now'
- Enter an ID
- If the path parameter
required
property is set totrue
, see error:Required field is not provided
, else see server responseHTTP 404 Not Found
forhttps://petstore.swagger.io/v2/pet/,
Expected behavior
The path parameter should interpolate properly regardless of whether or not it is required.
Screenshots
Path parameter required
property set to true
Path parameter required
property set to false
Additional context or thoughts
$ node -v
v12.14.0
The provided API definition is not valid. It's sort of a combination of OpenAPI 2 and 3. Please fix the definition first. You can use editor.swagger.io to see where the problems are. Also, according to the spec, path parameters are always required and cannot be set otherwise.
Sorry, modified the pet store example to OAS3 quickly as the project I'm working on hasn't been approved for open source yet. Updated the example above to one that passed AWS's API Gateway OAS3 import validation and confirmed that I can still duplicate the issue.
Thanks for the update. I've tried the revised definition in the online editor, and can't seem to reproduce the problem. When it's required, as it should be, it executes the call, and the case of it set as not required is not relevant.
So since you can't reproduce the issue via the online editor, does that invalidate what I've reported?
How can it be solved if it can't be reproduced?
Why request all the detail in the issue template if it won't be used to try and duplicate the issue as reported?
Added a complete example: https://github.com/tlindsay42/swagger-ui-5778.
Steps to reproduce:
-
git clone [email protected]:tlindsay42/swagger-ui-5778.git
-
cd ./swagger-ui-5778/
-
npm install
-
npm start
- Expand GET /pet/{petId}
- Click
Try it out
- Enter
1
for the ID and click theExecute
button - Receive error: Required field is not provided
- Delete line
45
in ./src/swagger.json:"required": true,
- Repeat steps 5-7
- Receive HTTP 404 error response due to ID interpolating to ',':
- Delete line 45 in ./src/swagger.json: "required": true,
Without this line the API definition becomes invalid because, according to the OpenAPI Specification, path parameters MUST be required.
Without this line the API definition becomes invalid because, according to the OpenAPI Specification, path parameters MUST be required.
Yep, I know. Just providing a troubleshooting observation as I found it interesting. The original error indicates that the path parameter variable is not being set with the supplied value, so I changed the path parameter to not required in order to see what value the path parameter variable is being set to, which is ','. Make sense?
Swagger UI expects a valid OpenAPI definition. If the API definition is invalid, correct functioning is not guaranteed.
It's the responsibility of the API definition provider to make sure the definition is correct. Swagger UI's sister project, Swagger Editor, includes a validation engine that will show OpenAPI syntax errors.
So, prior to step 9, the API definition is valid, right? Can we troubleshoot that error?
Sorry, I missed the error in step 8 and the fact that you were using React.
React applications are supposed to use the swagger-ui-react
module instead of swagger-ui
. Could you please try swagger-ui-react
instead and see if the issue persists?
I chose not to utilize the swagger-ui-react
module due to the lack of OAuth redirection handling support.
The swagger-ui
documentation doesn't mention anything about React not being supported. Is that the case?
Hello?
@hkosova Im getting "required field missing" errors on the official petstore API.
This definitely seems like a bug in swagger-ui
I have the sme issue. In my case with the headers.
This is my header filter:
And then..
I have the sme issue. In my case with de headers. This is my header filter:
And then..
Problem solved! In my case, I change "String" for "string", and now it's works!
I get a similar issue which may be related:
When calling (clicking 'execute') an api-endpoint with an optional path-parameter (required=false) a punctuation mark (,) is inserted in the call. In some situations the {name}
template is even inserted in the call (see reproductions).
swagger-ui 3.25.0 (Testing on latest chrome, MacOs Catalina)
my api definition:
{
"openapi": "3.0.0",
"info": {
"title": "OpenApi",
"version": "0.1.0"
},
"paths": {
"/status/motd/{name}": {
"get": {
"tags": [
"Status"
],
"operationId": "App\\Http\\Controllers\\StatusController::getMotd",
"parameters": [
{
"name": "name",
"in": "path",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
}
}
}
Reproducing in swagger-ui
Using no parameter (appends ','):
Using parameter (everything is fine here):
Using no parameter again (appends '{name}'):
What is wrong here? Or am i doing something wrong? Help appreciated. Thanks!
In fact, this isn't unique to path parameters or OpenAPI, and actually breaks all free-text string parameters. Not sure what has changed recently (maybe just more people using React) to mean this was only discovered now, cause it looks like it's been a problem for a while. I've checked, and it is still a problem in 3.25.0.
This and #1499 are caused by the onChange
method of DebounceInput
in JsonSchema_string
not firing.
I'd be up for trying to fix this but am not sure how to build in the way that swagger-ui
is (npm run build
builds in the way swagger-ui-dist
is, which does not have this bug).
What does work as a bit of a gross workaround for now is using the swagger-ui-dist
package instead. The README warns this will result in more data having to be transferred - which is true, but it's pretty marginal. In a very simple test case this changed the page size from 577 KB
to 642 KB
.
I've expanded a bit on @tlindsay42's example repo at https://github.com/domdomegg/swagger-ui-5778, which also shows the swagger-ui-dist workaround working (checkout https://github.com/domdomegg/swagger-ui-5778/commit/b511fd2a17eb8ca870f040cf0e57013f199317eb to see the buggy version).
@domdomegg @hkosova
This problem occur when swagger-ui and its dependency react-debounce-input use different versions of react. This happens because react-debounce-input has "react": "^15.3.0 || ^16.0.0"
, so if your project use react v16, it will use it too, but swagger-ui will use always v15. In that case, for some reason, setState's callback in react-debounce-input is not working, so onChange prop is not firing. So swagger-ui-dist works, because it has all dependencies in one file and forces react-debounce-input to use react v15.
For example, if you have react 16 in your project, then your node_modules will look like this:
-node_modules └ react(16) └ react-debounce-input(3.2.2) <- will use project react version └ swagger-ui ......└ node_modules .............└ react(15)
In this case, the problem occur, to fix this, you can force react-debounce-input to be installed in swagger-ui node_modules by installing older version of react-debounce-input, like this:
npm i --save-dev [email protected]
-node_modules └ react(16) └ react-debounce-input(3.1.0) └ swagger-ui .....└ node_modules ..........└ react(15) ................└ react-debounce-input(3.2.2) <- will use the same react version as swagger-ui
the proper solution would be to change somehow react-debounce-input dependency to "react": "^15.3.0"
swagger-ui-react doesn't help, its forced to use v16, but has a lot of deprecated stuff and i have a lot of warnings in console
Can confirm that both swagger-ui
and swagger-ui-react
have this issue with the onChange
events not triggering (and therefore never detecting input and required never clearing) when loaded in a React 16 project. I think it's high time this project is switched to React 16.
How to fix it today? removing the required field until this fixed lated?
Try to remove the "type":"integer"
for the path parameter(setting to string
also works). None of the examples at official docs have a type
attribute for the path parameter
This helped me to solve an example below. Example of not working .yml
file:
Return a user key information based on his name
---
tags:
- user
parameters:
- name: id
in: path
required: true
type: integer # <--- had to get rid of this to make it work
description: the id of the user to get
responses:
200:
description: The user's information was successfully retrieved
schema:
example:
user:
last_name: Doe
first_name: John
age: 30
How to fix it today? removing the required field until this fixed lated?
@alexsandro-xpt Use the swagger-ui-dist
package instead
Changing the type from "String" to "string" worked for me. https://swagger.io/docs/specification/data-models/data-types/
Changing the type from "String" to "string" worked for me. https://swagger.io/docs/specification/data-models/data-types/
Sounds like you're hitting a different bug. The below has the problem and uses "string" https://github.com/domdomegg/swagger-ui-5778/commit/b511fd2a17eb8ca870f040cf0e57013f199317eb
If it helps anyone, in my case the bug was caused by a duplicate parameter definition with required (somehow got duplicated when generating the openapi/swagger.json). Once the duplicate parameter definition was removed, everything worked just fine.
My case is also worked when I changes my schema from "String" to "string", but my another problem is that the header I am sending via Swagger is not getting added in my application's header array and I am not able to access it
We have a similar but maybe different issue. I am not sure. The online editor-next says our spec is valid, but required path params always fails in the ui. Even online.
So after debugging,... well not really. Just added some console outputs by best guess, because I did not want to check how this lib works. Nevertheless, I found that:
utils/index.js => validateValueBySchema was creating the error message and the issue I found is that:
let type = schema.get("type")
is not a string as it is handled in this method, but instead an immutable List. So I changed this:
let type = schema.get("type")
if(Im.List.isList(type) && type.size === 1) {
type = type.get(0);
}
And now it works for us. To be honest, I have no clue what I am doing here, but maybe somebody with experience in this project can check that.
It worked with me as follows:
`import { ApiProperty, ApiQuery } from '@nestjs/swagger'; import { Gender } from '@prisma/client'; import { IsIn, IsString } from 'class-validator'; export class SurveyPlansDto { @IsString() @ApiProperty({ name: 'gender', type: 'gender', required: false, description: 'gender', }) @isin([Gender.female, Gender.male]) gender: Gender;
@IsString() @ApiProperty({ type: Number, description: 'number of days', required: false, example: 3, }) daysNo: number; } ` add required and make sure its value is false, looks like swagger may take the required property as true by default