You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AsyncAPI (Could not dereference $ref in input) is this issue, and is on the CLI side.
Summary
For AsyncAPI input, the payload the CLI extracts and hands to Modelina still contains a document-absolute $ref pointing at #/components/schemas/..., but the document it points into is not passed along. Modelina re-dereferences that fragment as a standalone JSON Schema, cannot resolve the pointer, and fails.
Version: 0.81.1, also reproduces on main (with @asyncapi/modelina6.0.0-next.15).
$ codegen generate ./codegen.config.js
Generating code...
✗ Generation failed
Details:
Could not dereference $ref in input, is all the references correct? 1 error occurred while reading '<cwd>'
What is actually handed to Modelina
Dumping the input at the point Modelina dereferences it (JsonSchemaInputProcessor.dereferenceInputs):
The underlying error from @apidevtools/json-schema-ref-parser is:
Missing $ref pointer "#/components/schemas/Node". Token "components" does not exist.
Why this happens
src/codegen/inputs/asyncapi/parser.ts parses the document with @asyncapi/parser. Its resolver (@stoplight/json-ref-resolver) deliberately leaves circular $refs in place rather than materialising an infinite/cyclic structure. Non-recursive $refs get inlined; the self-reference does not.
src/codegen/inputs/asyncapi/generators/payloads.ts extracts a single payload with AsyncAPIInputProcessor.convertToInternalSchema(message.payload()) and wraps it as a standalone root with $schema: 'http://json-schema.org/draft-07/schema'.
src/codegen/output/modelina.ts passes that fragment to generator.generateCompleteModels(input, …).
Modelina routes it to its JSON Schema processor, whose processDraft7 calls dereferenceInputs. That tries to resolve #/components/schemas/Node against the fragment — which has no components key — and throws.
The pointer's target was left behind with the document, so this is not resolvable from inside Modelina: the input it receives genuinely does not contain the referenced schema. Modelina's own AsyncAPIInputProcessor does not hit this because it never re-dereferences — it goes straight from convertToInternalSchema to convertSchemaToMetaModel.
Deleting the children property makes the document generate fine, confirming the recursion (and hence the unresolved $ref) is the trigger, not the surrounding document.
Possible directions
Roughly in order of how self-contained they look from the outside — a maintainer will know better which fits the architecture:
Rewrite a self-pointer to # when the extracted payload is the schema being pointed at, so the fragment becomes self-contained.
Carry the referenced schemas along, e.g. emit the payload with a definitions/$defs section containing the reachable components/schemas entries and rewrite pointers accordingly.
Resolve the cycle into a real JavaScript object cycle before handing it over, which is what the OpenAPI path already effectively does via @readme/openapi-parser. Note this requires fix: do not serialize input during processor detection asyncapi/modelina#2624 (merged, unreleased at time of writing) to avoid the Converting circular structure to JSON crash.
Notes
Recursive structures are common in real documents — category trees, comment threads, nested rule/filter expressions, JSON-Schema-shaped payloads.
For reference, the OpenAPI half of #447 now generates correctly once the Modelina fix is in place, producing the expected self-referencing model:
Split out of #447, which reported recursive
$reffailures for both OpenAPI and AsyncAPI input. Those turned out to have two unrelated causes:Converting circular structure to JSON) was a Modelina bug, fixed in fix: do not serialize input during processor detection asyncapi/modelina#2624.Could not dereference $ref in input) is this issue, and is on the CLI side.Summary
For AsyncAPI input, the payload the CLI extracts and hands to Modelina still contains a document-absolute
$refpointing at#/components/schemas/..., but the document it points into is not passed along. Modelina re-dereferences that fragment as a standalone JSON Schema, cannot resolve the pointer, and fails.Version:
0.81.1, also reproduces onmain(with@asyncapi/modelina6.0.0-next.15).Reproduction
asyncapi.yaml:codegen.config.js:What is actually handed to Modelina
Dumping the input at the point Modelina dereferences it (
JsonSchemaInputProcessor.dereferenceInputs):{ "type": "object", "$schema": "http://json-schema.org/draft-07/schema", "required": ["label"], "properties": { "label": { "type": "string", "x-parser-schema-id": "<anonymous-schema-1>", "x-modelgen-inferred-name": "NodeLabel" }, "children": { "type": "array", "items": { "$ref": "#/components/schemas/Node", "x-parser-schema-id": "<anonymous-schema-3>", "x-modelgen-inferred-name": "NodeChildrenItem" }, "x-parser-schema-id": "<anonymous-schema-2>", "x-modelgen-inferred-name": "NodeChildren" } }, "x-parser-schema-id": "Node", "x-modelgen-inferred-name": "root", "$id": "Node" }The underlying error from
@apidevtools/json-schema-ref-parseris:Why this happens
src/codegen/inputs/asyncapi/parser.tsparses the document with@asyncapi/parser. Its resolver (@stoplight/json-ref-resolver) deliberately leaves circular$refs in place rather than materialising an infinite/cyclic structure. Non-recursive$refs get inlined; the self-reference does not.src/codegen/inputs/asyncapi/generators/payloads.tsextracts a single payload withAsyncAPIInputProcessor.convertToInternalSchema(message.payload())and wraps it as a standalone root with$schema: 'http://json-schema.org/draft-07/schema'.src/codegen/output/modelina.tspasses that fragment togenerator.generateCompleteModels(input, …).processDraft7callsdereferenceInputs. That tries to resolve#/components/schemas/Nodeagainst the fragment — which has nocomponentskey — and throws.The pointer's target was left behind with the document, so this is not resolvable from inside Modelina: the input it receives genuinely does not contain the referenced schema. Modelina's own
AsyncAPIInputProcessordoes not hit this because it never re-dereferences — it goes straight fromconvertToInternalSchematoconvertSchemaToMetaModel.Deleting the
childrenproperty makes the document generate fine, confirming the recursion (and hence the unresolved$ref) is the trigger, not the surrounding document.Possible directions
Roughly in order of how self-contained they look from the outside — a maintainer will know better which fits the architecture:
#when the extracted payload is the schema being pointed at, so the fragment becomes self-contained.definitions/$defssection containing the reachablecomponents/schemasentries and rewrite pointers accordingly.@readme/openapi-parser. Note this requires fix: do not serialize input during processor detection asyncapi/modelina#2624 (merged, unreleased at time of writing) to avoid theConverting circular structure to JSONcrash.Notes
Recursive structures are common in real documents — category trees, comment threads, nested rule/filter expressions, JSON-Schema-shaped payloads.
For reference, the OpenAPI half of #447 now generates correctly once the Modelina fix is in place, producing the expected self-referencing model:
The AsyncAPI case above is unaffected by that fix and still fails.