43

Unable to render this definition The provided definition does not specify a valid version field.

Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: "2.0" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).

Where do I need to insert the correct version to the stop the error below. Swagger editor works ok, but when launching a particular project I receive this error. First time using Swagger.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Paddy Popeye
  • 1,634
  • 1
  • 16
  • 29
  • _"but when launching a particular project"_ - which project? How do you launch it? Can you post the OpenAPI YAML/JSON file from this project? The more details, the easier it is for others to figure out what the problem is and how to fix it. – Helen Aug 21 '18 at 15:18
  • launched with npm start. the project is git+https://github.com/HaiderMalik12/build-and-secure-restful-api.git .I see no OpenAPI YAML/JSON. Think this might be the issue ?? – Paddy Popeye Aug 21 '18 at 15:23
  • 2
    Please confirm whether `/v2/api-docs` is accessible. – Yayun Du Jan 09 '19 at 11:24
  • i had to pass v2 spec to query form. could not make it work with v3 due to "ambigous handler method mapped for '/v3/api-docs' ex. i was using springfox-boot-starter 3.0.0. – Simon Logic Feb 12 '21 at 15:57

14 Answers14

18

Your API definition is missing the OpenAPI/Swagger version number, in this case "swagger": "2.0". Add it at the beginning, like so:

{
    "swagger": "2.0",

    "title" : "Music API Documentation",
    ...
Helen
  • 87,344
  • 17
  • 243
  • 314
  • 14
    I have `openapi: 3.0.0` on 1st line but i get this – shorif2000 Mar 27 '20 at 16:17
  • @shorif2000 The problem might be somewhere else. Please [ask a new question](/questions/ask?tags=openapi+swagger-ui) and post your OpenAPI file. – Helen Mar 27 '20 at 16:23
  • @shorif2000 Although I had openpi, I had to add swagger too. – aderchox Mar 04 '23 at 16:05
  • this worked for me also and for more options checkout this link https://copyprogramming.com/howto/swagger-unable-to-render-this-definition-the-provided-definition-does-not-specify-a-valid-version-field?utm_content=cmp-true – Isaacs Katongole Mar 14 '23 at 14:09
12

I encountered this same problem today. In my case it is the Gson configuration which lead to the error. If you are also using Gson with SpringMVC, may be you could try this out:

I am setting up a rest-api project using spring boot 2.2.4 and spring fox swagger 2.9.2 . Since I am more familiar with Gson than Jackson, I replaced the default MessageConverter:

@Configuration
@EnableWebMvc
public class MvcConfiguration implements WebMvcConfigurer {

    private final Gson gson = new Gson();

    // ......

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
        gsonHttpMessageConverter.setGson(gson);
        converters.add(gsonHttpMessageConverter);
    }

    // ......

}

After that the "http://localhost:8080/swagger-ui.html" breaks like the question described. Then I typed "http://localhost:8080/v2/api-docs" in browser and noticed the swagger doc was wrapped into another layer, with an unnecessary "value" field like this:

{
    value: "{"swagger":"2.0","info":{"description": ......}}"
}

No doubt swagger cannot find the "swagger":"2.0" field if api-docs yields something like that. The value of "value" field is the actual swagger doc.

After some search I found that swagger doc will be incorrectly serialized by Gson if you leave it be. The solution is simple - register a serializer for swagger to your Gson bean:

private final Gson gson = new GsonBuilder()
        .registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter())
        .create();

private static class SpringfoxJsonToGsonAdapter implements JsonSerializer<Json> {
    @Override
    public JsonElement serialize(Json json, Type type, JsonSerializationContext context) {
        final JsonParser parser = new JsonParser();
        return parser.parse(json.value());
    }
}

where Json is a class provided by springfox:

import springfox.documentation.spring.web.json.Json;

Hope this would help.

Lyux
  • 431
  • 6
  • 12
  • Thanks for this! It solved my problem. Btw, `parser.parse(json.value())` seems to be deprecated, so I used the static method `JsonParser.parseString(json.value())` instead. Cheers! – Kenan Güler Jun 06 '20 at 23:38
6

I've ran into this twice now with a .net core project.

In the Configure method of Startup.cs I needed to validate the path of the json that was rendered for the UI. That should look something like:

app.UseSwaggerUI(c => { c.SwaggerEndpoint("./v1/swagger.json", "MyServiceAPI"); });
Osama AbuSitta
  • 3,918
  • 4
  • 35
  • 51
David G
  • 161
  • 2
  • 6
  • 2
    This answer worked for me. Swagger worked fine on my local machine, but would not work on the server (same error message as OP) until I made this change. Thanks! – AlfredBr Jun 07 '21 at 21:08
6

This solution helps you if your API definition (browse to your api-docs endpoint) is JSON and has escaped double quotes in it.

The issue is that the endpoint returns a String that contains JSON. Spring now tries to find a message converter that converts String to JSON because the request mapping defines a produces = MediaType.APPLICATION_JSON_VALUE. This will be (in my case) the Jackson message converter (MappingJackson2HttpMessageConverter to be specific) which converts the string to JSON.

To fix this problem you have to add a StringHttpMessageConverter before the MappingJackson2HttpMessageConverter.

StringHttpMessageConverter messageConverter = new StringHttpMessageConverter();
messageConverter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.ALL));
converters.add(messageConverter);

Notice that MediaType.APPLICATION_JSON is added to the list of supported MediaTypes of the converter.

Now Spring will cycle through the converters in order and find the String message converter as a suitable converter.

T3rm1
  • 2,299
  • 5
  • 34
  • 51
1

Encountered a similar case, swagger libraries in use on pom are;

 <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
     </dependency>
     <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
     </dependency>  

On Application.java specify Docket Bean

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.context.annotation.Bean;

import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * Created by nyakundid
 */
@EnableScheduling
@EnableAsync
@SpringBootApplication
@EnableSwagger2
public class Application implements CommandLineRunner {

    public Log log = LogFactory.getLog(Application.class);


    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2).select()
                .apis(RequestHandlerSelectors.basePackage("com.package.controller")).build();
    }
}

and finally create your controller under the basePackage Hope it works for you.

Duncan O. N.
  • 778
  • 12
  • 24
1

Nothing here worked for me because I was using yaml instead of JSON.

What I did to solve the problem involved changing the openapi version at the start from openapi: 3.0.0 to openapi: 3.0.1

Spevacus
  • 584
  • 2
  • 13
  • 23
  • SpevacusSanyaolu Adefemi, this does not provide an answer to the question. You can [search for similar questions](/search), or refer to the related and linked questions on the right-hand side of the page to find an answer. If you have a related but different question, [ask a new question](/questions/ask), and include a link to this one to help provide context. See: [Ask questions, get answers, no distractions](/tour) – Luca Kiebel Jan 31 '22 at 09:56
0

Here is a solution for this problem with OpenAPI V3 that worked for me. I assume this can be related for other versions as well.

I experimented with Gson instead of Jackson as Spring's default serializer. The /v3/api-docs that Gson generates is wrapped in double quotes. Thus the /swagger-ui/index.html shows the error addressed in this thread.

Reverting to Jackson solved this for me. If you must use Gson, maybe the solution @Lyux wrote above can suit you.

Boris
  • 471
  • 4
  • 8
0

I have met this problem also , in my case /v3/api-doc is intercepted by LoginInterceptor, my solution is:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (request.getRequestURI().startsWith("/swagger") || "/v3/api-docs".equals(request.getRequestURI())) {
            return true;
        }

}
zhuguowei
  • 8,401
  • 16
  • 70
  • 106
0

had same error , working locally on my computer ,when go to staging server give me this error , i resolved it by using the below code

app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "APIName"); });
Ali
  • 1,080
  • 16
  • 22
0

I am working on a SpringBoot project, with no UI components. The assumption is that you have already done the work to return your GroupedOpenApi and OpenApi functions and you are triaging it not showing your yaml in the swagger-ui.

Actual issue: The yaml was returned with all quotes escaped. As shown here:

"{\"openapi\":\"3.0.1\",\"info\":{\"t

Create a WebServlet to intercept the yaml being returned. You only needed the first part of this:

https://www.javafixing.com/2022/03/fixed-understand-and-configure-spring.html

Add a Endpoint Handler to broker the response. Add this verbatim (remove the ", null" from the return of the first function):

https://stackoverflow.com/a/70977335/877552

Lodlaiden
  • 361
  • 1
  • 10
0

If you're using swagger-express-ui with tsoa, you might see this error if your swaggerUi.setup function failed to detect any swagger.json file to import its schema from. To solve this problem you might either import this file locally or by loading it from a URL. Here are two ways to perform this:

const options = {
  swaggerOptions: {
    url: 'http://petstore.swagger.io/v2/swagger.json',
   },
};

app.use('/docs', swaggerUi.serve, swaggerUi.setup(undefined, options));
app.use('/api/v1', router);

const swaggerDocument = require('../swagger.json');

app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

Note: Eslint might be bothered by the require statement, if you don't want to disable it you can use await instead:

app.use(
 "/docs",
 swaggerUi.serve,
 async (_req: Request, res: Response) =>
 res.send(swaggerUi.generateHTML(await import("../swagger.json"))));
Jood80
  • 124
  • 2
  • 4
0
import * as swaggerDocument from './assets/swagger.json'; 

helped for me instead of

import swaggerDocument from './assets/swagger.json';
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
0

I faced a similar error when deploying my application to the staging environment, but it was running fine on my local setup. Upon checking the network tab, I found that Swagger UI makes two API calls to fetch the required details for rendering:

  • swagger-config
  • api-docs

These calls were happening without the staging prefix (some-service) in the URL.

  • Local Swagger URL: http://localhost:9292/swagger-ui/index.html#/
  • Staging Swagger URL: https://stage-swagger.infra.in/some-service/swagger-ui/index.html#/

Adding the appropriate configuration to application.properties resolved the issue:

springdoc.swagger-ui.config-url = /some-service/v3/api-docs/swagger-config springdoc.swagger-ui.url = /some-service/v3/api-docs

0

I feel a bit 'me too' on this, but it's a good set of answers that fundamentally address the question title. All the answers provided indicate the many ways the incorrect json/yaml is presented to the swagger ui parser.

For me, my Azure Function (Typescript) was returning parsed Json instead of what was streamed from file. The output from the swagger-jsdoc file was good to be returned and didn't need to be parsed:

    const fs = require('fs').promises;
    const path = __dirname + '/../../../../swagger.json';

    data = await fs.readFile(path, 'utf8');
    Log.info('Return this:', data);


    result = JSON.parse(data);
    Log.info('Do not return this:', result);

    return { body: data }; // <== See, return 'data'

When I was returning result I got the error message, but when returning data the problem was solved.

Aiden Dipple
  • 134
  • 2
  • 15