{"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"component-name-unique","__idx":0},"children":["component-name-unique"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Verifies component names are unique."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"OAS"},"children":["OAS"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Compatibility"},"children":["Compatibility"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["2.0"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["❌"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["3.0"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["✅"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["3.1"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["✅"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["3.2"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["✅"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"api-design-principles","__idx":1},"children":["API design principles"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When generating code based on an OpenAPI description, there are various different problems when component names are not"," ","unique through the whole spec."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["schema: The code generator creates a class for each schema."," ","If they are not uniquely named, the generator appends numbers. These numbers are non-deterministic."," ","By adding a new schema with the same component name it could change the name (appended number) of another one."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["parameter: The code generator creates a class for each parameter."," ","If they are not uniquely named, the generator appends numbers. These numbers are non-deterministic."," ","By adding a new parameter with the same component name it could change the name (appended number) of another one."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["response: The code generator tends to reuse the first one and drops the other ones with the same component name."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["requestBody: The code generator tends to reuse the first one and drops the other ones with the same component name."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This clearly is not optimal. Having unique component names prevents these problems."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"configuration","__idx":2},"children":["Configuration"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Option"},"children":["Option"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Type"},"children":["Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["severity"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Possible values: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["off"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},". Default ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["off"]}," (in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recommended"]}," configuration)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["schemas"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Possible values: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["off"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},". Default: not set."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["parameters"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Possible values: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["off"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},". Default: not set."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["responses"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Possible values: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["off"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},". Default: not set."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["requestBodies"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Possible values: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["off"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},". Default: not set."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["strategy"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["string"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Possible values: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["basename"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]},". Default: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["basename"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["An example configuration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"rules:\n  component-name-unique:\n    schemas: error\n    parameters: off\n    responses: warn\n    requestBodies: warn\n    strategy: basename\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"component-names-strategy","__idx":3},"children":["Component names strategy"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The rule predicts the component names that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," produces, so ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["strategy"]}," must match the ",{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/v2/commands/bundle#configure-the-component-names-strategy"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--component-names-strategy"]}]}," option you bundle with."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With the default ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["basename"]},", a schema pulled in from another file is named after the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$ref"]}," fragment or the file name."," ","Two files both called ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Order.yaml"]}," therefore collide, and the rule reports them."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["With ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]},", the same schemas are named after their ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]}," field instead."," ","Two files called ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Order.yaml"]}," with the titles ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Order model"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Order request"]}," become ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OrderModel"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OrderRequest"]},", so the rule no longer reports them."," ","Two schemas in differently named files that share a title do collide, and the rule reports those instead."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]}," strategy applies to every schema that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," renames."," ","Every ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$ref"]}," except those fully inside the root document."," ","A referenced schema that has no ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]}," can't be named under this strategy, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bundle"]}," fails without producing a file."," ","The rule reports these schemas, so you find them before bundling."," ","For the uniqueness check itself, such schemas still fall back to their file names, so a name collision is reported as well."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"examples","__idx":4},"children":["Examples"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Given this configuration:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"rules:\n  component-name-unique: error\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-of-incorrect-schema-files","__idx":5},"children":["Example of ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["incorrect"]}," schema files"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["file1.yaml:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"components:\n  schemas:\n    FooSchema:\n      type: object\n      properties:\n        field:\n          $ref: './file2.yaml#/components/schemas/FooSchema'\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["file2.yaml:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"components:\n  schemas:\n    FooSchema:\n      type: object\n      properties:\n        otherField:\n          type: string\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-of-correct-schema-files","__idx":6},"children":["Example of ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["correct"]}," schema files"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["file1.yaml:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"components:\n  schemas:\n    FooSchema:\n      type: object\n      properties:\n        field:\n          $ref: './file2.yaml#/components/schemas/AnotherFooSchema'\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["file2.yaml:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"yaml","header":{"controls":{"copy":{}}},"source":"components:\n  schemas:\n    AnotherFooSchema:\n      type: object\n      properties:\n        otherField:\n          type: string\n","lang":"yaml"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"relates-rules","__idx":7},"children":["Relates rules"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"Link","attributes":{"href":"https://github.com/Redocly/redocly-cli/blob/main/packages/core/src/rules/oas3/component-name-unique.ts"},"children":["Rule source"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"Link","attributes":{"href":"/docs/cli/rules/oas/no-unused-components"},"children":["no-unused-components"]}]}]}]},"frontmatter":{"slug":"/docs/cli/rules/oas/component-name-unique"},"tagList":[],"title":"component-name-unique","lastModified":"2026-09-10T14:23:29.000Z"}