Skip to content

[BUG] Error resolving complex Reference with path parameter #21058

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
5 tasks done
arrrno opened this issue Apr 8, 2025 · 2 comments
Open
5 tasks done

[BUG] Error resolving complex Reference with path parameter #21058

arrrno opened this issue Apr 8, 2025 · 2 comments

Comments

@arrrno
Copy link

arrrno commented Apr 8, 2025

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
Description

I have a root OpenAPI declaration file that makes paths references to another declaration's path in another file.
The path in question has a path parameter /my-resource/{my-path-param}

When trying to generate the models from the root declaration file, I'm getting the following error:

ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving ./acls.yaml#/paths/~1acls~1{aclName}
 -Illegal character in fragment at index 27: ./acls.yaml#/paths/~1acls~1{aclName}

The problem is with the "{" behind the second ~1.

Other cases where no path parameter is provided, are working fine.

openapi-generator version

7.12.0

OpenAPI declaration file content or url
Root OpenAPI declaration file example
openapi: 3.1.2
info:
  title: Root OpenAPI declaration file
  version: 1.0.0
paths:
  /acls/{aclName}:
    $ref: 'acls.yaml#/paths/~1acls~1{aclName}'
Sub OpenAPI declaration file example 'acls.yaml'
openapi: 3.1.2
info:
  title: Jupiter agent Sub-swagger for Acls
  version: 1.0.0

paths:
  /acls/{aclName}:
    get:
      summary: Get an Acl by Name
      operationId: getAclByName
      parameters:
        - name: aclName
          in: path
          description: Name of acl to return
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: string
Generation Details
generatorName: spring
outputDir: generated
inputSpec: src/main/resources/api.yaml
additionalProperties:
  groupId: org.openapitools.openapi3
  artifactId: spring-acls
  snapshotVersion: "true"
Steps to reproduce
  • create a root file root.yaml
openapi: 3.1.2
info:
  title: Root OpenAPI declaration file
  version: 1.0.0
paths:
  /acls/{aclName}:
    $ref: 'acls.yaml#/paths/~1acls~1{aclName}'
  • at the same level, create a acls.yaml file
openapi: 3.1.2
info:
  title: Jupiter agent Sub-swagger for Acls
  version: 1.0.0

paths:
  /acls/{aclName}:
    get:
      summary: Get an Acl by Name
      operationId: getAclByName
      parameters:
        - name: aclName
          in: path
          description: Name of acl to return
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: string
  • run the CLI
 openapi-generator-cli generate -i root.yaml --group-id org.openapitools.openapi3 --artifact-id spring-acls --artifact-version 0.0.1-SNAPSHOT -g spring -o generated

You should get the following error stack

[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving ./acls.yaml#/paths/~1acls~1{aclName}
java.net.URISyntaxException: Illegal character in fragment at index 27: ./acls.yaml#/paths/~1acls~1{aclName}
        at java.base/java.net.URI$Parser.fail(URI.java:2974)
        at java.base/java.net.URI$Parser.checkChars(URI.java:3145)
        at java.base/java.net.URI$Parser.parse(URI.java:3189)
        at java.base/java.net.URI.<init>(URI.java:623)
        at io.swagger.v3.parser.reference.ReferenceUtils.toBaseURI(ReferenceUtils.java:15)
        at io.swagger.v3.parser.reference.ReferenceVisitor.toBaseURI(ReferenceVisitor.java:65)
        at io.swagger.v3.parser.reference.ReferenceVisitor.toReference(ReferenceVisitor.java:69)
        at io.swagger.v3.parser.reference.ReferenceVisitor.resolveRef(ReferenceVisitor.java:205)
        at io.swagger.v3.parser.reference.ReferenceVisitor.visitPathItem(ReferenceVisitor.java:108)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:383)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:933)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
        at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
        at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
        at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
        at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
        at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
        at org.openapitools.codegen.config.CodegenConfigurator.toContext(CodegenConfigurator.java:686)
        at org.openapitools.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:744)
        at org.openapitools.codegen.cmd.Generate.execute(Generate.java:527)
        at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
        at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
[main] ERROR i.s.v.p.reference.ReferenceVisitor - Error resolving ./acls.yaml#/paths/~1acls~1{aclName}
java.net.URISyntaxException: Illegal character in fragment at index 27: ./acls.yaml#/paths/~1acls~1{aclName}
        at java.base/java.net.URI$Parser.fail(URI.java:2974)
        at java.base/java.net.URI$Parser.checkChars(URI.java:3145)
        at java.base/java.net.URI$Parser.parse(URI.java:3189)
        at java.base/java.net.URI.<init>(URI.java:623)
        at io.swagger.v3.parser.reference.ReferenceUtils.toBaseURI(ReferenceUtils.java:15)
        at io.swagger.v3.parser.reference.ReferenceVisitor.toBaseURI(ReferenceVisitor.java:65)
        at io.swagger.v3.parser.reference.ReferenceVisitor.toReference(ReferenceVisitor.java:69)
        at io.swagger.v3.parser.reference.ReferenceVisitor.resolveRef(ReferenceVisitor.java:205)
        at io.swagger.v3.parser.reference.ReferenceVisitor.visitPathItem(ReferenceVisitor.java:108)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem(OpenAPI31Traverser.java:383)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap(OpenAPI31Traverser.java:933)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths(OpenAPI31Traverser.java:197)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi(OpenAPI31Traverser.java:124)
        at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse(OpenAPI31Traverser.java:65)
        at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference(OpenAPIDereferencer31.java:74)
        at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:227)
        at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
        at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
        at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
        at org.openapitools.codegen.config.CodegenConfigurator.toContext(CodegenConfigurator.java:686)
        at org.openapitools.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:744)
        at org.openapitools.codegen.cmd.Generate.execute(Generate.java:527)
        at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
        at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
Exception in thread "main" org.openapitools.codegen.SpecValidationException: There were issues with the specification. The option can be disabled via validateSpec (Maven/Gradle) or --skip-validate-spec (CLI).
 | Error count: 1, Warning count: 0
Errors:
        -Illegal character in fragment at index 27: ./acls.yaml#/paths/~1acls~1{aclName}

        at org.openapitools.codegen.config.CodegenConfigurator.toContext(CodegenConfigurator.java:717)
        at org.openapitools.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:744)
        at org.openapitools.codegen.cmd.Generate.execute(Generate.java:527)
        at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
        at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)

Related issues/PRs
Suggest a fix

EDIT: (04/14/2025)
As an ugly workaround, it seems that replacing { by %7B and } by %7D can do the trick, but, unfortunately it does not respect the openapi specs

@arrrno
Copy link
Author

arrrno commented Apr 15, 2025

I managed to workaround this issue and keep on respecting the OAS, while hoping this will get fixed in the future.

For those who are in the same case than me, here is my little contribution. Hopefully it will save lives 😁

Below is an excerpt of my pom.xml

This will basically copy your swagger sources to the build dir, replace the { and } by %7B and %7C in your root swagger file, and provide the result to openapi-generator.

Note, that if you are using Windows you will have to use URI format for inputSpec. (related to other issue: 14648

[...]
<properties>
        <project.build.uri>${project.baseUri}/target</project.build.uri>
        <project.src.swagger.baseDir>${project.basedir}/src/main/resources/swagger</project.src.swagger.baseDir>
        <project.src.swagger.fileName>api.yaml</project.src.swagger.fileName>
        <project.build.generatedSources.baseDir>${project.build.directory}/generated-sources/</project.build.generatedSources.baseDir>
        <project.build.swagger.baseDir>${project.build.generatedSources.baseDir}/swagger</project.build.swagger.baseDir>
        <openapi.generator.inputSpec>${project.build.uri}/generated-sources/swagger/${project.src.swagger.fileName}</openapi.generator.inputSpec>
        <openapi.generator.output>${project.build.generatedSources.baseDir}/openapi</openapi.generator.output>
    </properties>
[...]
 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>convert-for-compatibility-openapi-generator</id>
                        <phase>generate-sources</phase>
                        <configuration>
                            <target>
                                <copy todir="${project.build.swagger.baseDir}">
                                    <fileset dir="${project.src.swagger.baseDir}" />
                                </copy>
<!--                                Since there is a bug in openapi-generator we are obliged to replace the { and } by %7B and %7D-->
<!--                                https://github.com/OpenAPITools/openapi-generator/issues/21058-->
                                <replace file="${project.build.swagger.baseDir}/${project.src.swagger.fileName}" token="~1{" value="~1%7B" />
                                <replace file="${project.build.swagger.baseDir}/${project.src.swagger.fileName}" token="}'" value="%7D'" />
                            </target>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>7.12.0</version>
                <executions>
                    <execution>
                        <id>generate-models</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${openapi.generator.inputSpec}</inputSpec><!-- use of Uri otherwise not working on f***g Windows-->
                            <generatorName>spring</generatorName>
                            <output>${openapi.generator.output}</output>
                            <modelPackage>${project.groupId}.model</modelPackage>
                            <apiPackage>${project.groupId}.api</apiPackage>
                            <generateModels>true</generateModels>
                            <generateApis>true</generateApis>
                            <generateApiTests>false</generateApiTests>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

@xardbaiz
Copy link

xardbaiz commented May 7, 2025

Same for me (org.openapi.generator v7.13.0).
Might be related to earlier swagger-api/swagger-parser#2159
Thanks for workarounds though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants