AsyncAPI: a $ref to a plain-name anchor of a component schema fails with "Unresolved $id reference"

Open Beginner friendly
#6,841 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
70/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
tooling

Research direction

Read AsyncAPIParser.parse_raw in parser/asyncapi.py next to OpenAPIParser.parse_raw, and see where the latter calls prepare_schema_resources from parser/_schema_documents.py before resolving $refs. Reproduce with the asyncapi.yaml snippet and compare the output against the OpenAPI run. Done means the AsyncAPI document yields User and SignUp with SignUp.user typed User, plus a regression test next to the existing AsyncAPI parser tests.

Written by the indexing model from the issue text.

Description

bug

In an AsyncAPI document, a component schema that names itself with a plain-name fragment ($id: '#user', or
$anchor: user) cannot be referenced by that name: generation stops with "Unresolved $id reference". The same
schemas in an OpenAPI 3.1 document generate fine.

asyncapi.yaml:

asyncapi: 3.0.0
info:
  title: Users
  version: 1.0.0
channels:
  userSignedUp:
    address: user/signedup
    messages:
      UserSignedUp:
        payload:
          $ref: '#/components/schemas/SignUp'
components:
  schemas:
    User:
      $id: '#user'
      type: object
      properties:
        name:
          type: string
    SignUp:
      type: object
      properties:
        user:
          $ref: '#user'
datamodel-codegen --input asyncapi.yaml --input-file-type asyncapi --output-model-type pydantic_v2.BaseModel --disable-timestamp

Output (exit status 2):

Unresolved $id reference '#user' in scope 'asyncapi.yaml'. Known $id values: <none>

Writing $anchor: user instead of $id: '#user' gives the same error, and so does a message payload of
$ref: '#user'.

The same components in an OpenAPI 3.1 document, openapi.yaml:

openapi: 3.1.0
info:
  title: Users
  version: 1.0.0
paths: {}
components:
  schemas:
    User:
      $anchor: user
      type: object
      properties:
        name:
          type: string
    SignUp:
      type: object
      properties:
        user:
          $ref: '#user'
datamodel-codegen --input openapi.yaml --input-file-type openapi --output-model-type pydantic_v2.BaseModel --disable-timestamp
class User(BaseModel):
    name: str | None = None


class SignUp(BaseModel):
    user: User | None = None

Expected: the AsyncAPI document generates the same User and SignUp models, with SignUp.user typed User.

Also in 0.86.0.

Cause: parser/asyncapi.py:AsyncAPIParser.parse_raw indexes the document without
parser/_schema_documents.py:prepare_schema_resources, which OpenAPIParser.parse_raw calls; so the component
schemas are never registered as schema resources and their plain-name anchors are unknown when a $ref is resolved.

Dominant language
Python
Stars
4k
Forks
460
Avg merge
6h 12m
Merged PRs (30d)
923

Getting set up

  • Ships a Dockerfile or Docker Compose file
  • No pull request template
  • No contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from datamodel-code-generator/datamodel-code-generator

All issues in datamodel-code-generator/datamodel-code-generator

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.