Skip to content

[Bug]: Array items $ref to an external file is not resolved to #/components/schemas/... when it's the only $ref in the referencing file #2409

Open

Description

@rehevkor5

Description

When a component schema is externalized to its own file and that file contains an array whose items is a $ref
to another external file, the items $ref is left as the raw relative file path (./schemas/Item.yaml) instead of
being resolved to #/components/schemas/Item, unless the same external file also has a top-level property that is itself a bare $ref.

There is no entry in SwaggerParseResult#getMessages(). With resolveFully=true the items ref is also not
inlined. Because of this, the openapi-generator library cannot resolve the leftover file ref and generates List<Object> instead of List<Item> (it logs Failed to get the schema name: ./schemas/Item.yaml and
Error obtaining the datatype from ref: ./schemas/Item.yaml. Default to 'object').

Affected Version

2.1.48

Earliest version the bug appears in (if known):
2.1.33 (couldn't test older versions than that)

Steps to Reproduce

Note that the spec is 3.0 not 3.1, 3.1 doesn't appear to have this problem.

openapi.yaml

openapi: 3.0.3
info:
  title: Array items $ref repro
  version: "1"
paths:
  /broken:
    get:
      operationId: getBroken
      responses:
        "200":
          description: ok
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Broken"
  /working:
    get:
      operationId: getWorking
      responses:
        "200":
          description: ok
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Working"
components:
  schemas:
    Item:
      $ref: "./schemas/Item.yaml"
    Broken:
      $ref: "./schemas/Broken.yaml"
    Working:
      $ref: "./schemas/Working.yaml"

schemas/Item.yaml

type: object
properties:
  name:
    type: string

schemas/Broken.yaml (the array's items is the only $ref in the file)

type: object
properties:
  items:
    type: array
    items:
      $ref: "./Item.yaml"

schemas/Working.yaml (identical, plus one unrelated top-level property $ref)

type: object
properties:
  items:
    type: array
    items:
      $ref: "./Item.yaml"
  extra:
    $ref: "./Item.yaml"

Run this code:

ParseOptions options = new ParseOptions();
options.setResolve(true);
SwaggerParseResult result = new OpenAPIV3Parser().readLocation("openapi.yaml", null, options);
Schema broken = result.getOpenAPI().getComponents().getSchemas().get("Broken");
Schema working = result.getOpenAPI().getComponents().getSchemas().get("Working");
System.out.println(((Schema) broken.getProperties().get("items")).getItems().get$ref());
System.out.println(((Schema) working.getProperties().get("items")).getItems().get$ref());

Expected Behavior

Both print #/components/schemas/Item (or, with resolveFully=true, both are inlined as an object schema with
name).

Actual Behavior

With setResolve(true):

Schema items.getItems().get$ref()
Broken ./schemas/Item.yaml (not resolved)
Working #/components/schemas/Item

With setResolve(true) + setResolveFully(true): Working is inlined, Broken is unchanged
(./schemas/Item.yaml). getMessages() is empty in all cases, and components.schemas contains [Item, Broken, Working] with no extra keys. This behavior is unexpected and not self-consistent.

Logs / Stack Traces

No parser warning at debug level.

However, openapi-generator logs messages like this:

[WARNING] ./schemas/Item.yaml is not defined
[WARNING] Failed to get the schema name: ./schemas/Item.yaml
[WARNING] Error obtaining the datatype from ref: ./schemas/Item.yaml. Default to 'object'

Environment

  • Java version:
  • Build tool:
  • OS:

Additional Context

OpenAPITools/openapi-generator#2249 might share the same root cause, but it's not obvious

Checklist

  • I have searched the existing issues and this is not a duplicate.
  • I have provided sufficient information for maintainers to reproduce the issue.

Activity

  1. vinirib commented on Oct 29, 2026

    @vinirib

    I reproduced this on current master (2.1.49-SNAPSHOT). The property name is not a factor: renaming items to something else fails the same way.

    Root cause is the second pass in ComponentsProcessor.processSchemas. After the first pass, ExternalRefProcessor leaves refs between external files rewritten relative to the root (./Item.yaml becomes ./schemas/Item.yaml), and the second pass is what turns them into #/components/schemas/.... That pass only reprocesses a model when one of its direct properties has a $ref:

    if(property.get$ref() != null) {
        schemaProcessor.processSchema(model);
    }

    In Broken.yaml the only pending ref sits inside the array items, one level down, so the model is skipped. In Working.yaml the bare extra ref triggers a reprocess of the whole model, which resolves items as a side effect.

    I'd like to work on this. The fix I have in mind reprocesses a model once when it has a pending external ref at any depth (properties, items, additionalProperties, allOf/anyOf/oneOf, not), with a visited set to stay safe on recursive schemas. I'll open a PR with tests covering both resolve and resolveFully.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions