Title: OpenAPI 3.1: schemas with const but no type lose type information · Issue #2567 · oapi-codegen/oapi-codegen · GitHub
Open Graph Title: OpenAPI 3.1: schemas with const but no type lose type information · Issue #2567 · oapi-codegen/oapi-codegen
X Title: OpenAPI 3.1: schemas with const but no type lose type information · Issue #2567 · oapi-codegen/oapi-codegen
Description: A schema containing only const, without an explicit type, generates an alias to any. This affects all constants: scalars, arrays and objects. The reproduction below compares scalar const schemas with their explicitly typed equivalents. R...
Open Graph Description: A schema containing only const, without an explicit type, generates an alias to any. This affects all constants: scalars, arrays and objects. The reproduction below compares scalar const schemas wi...
X Description: A schema containing only const, without an explicit type, generates an alias to any. This affects all constants: scalars, arrays and objects. The reproduction below compares scalar const schemas wi...
Opengraph URL: https://github.com/oapi-codegen/oapi-codegen/issues/2567
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"OpenAPI 3.1: schemas with const but no type lose type information","articleBody":"A schema containing only `const`, without an explicit `type`, generates an alias to `any`. This affects all constants: scalars, arrays and objects.\n\nThe reproduction below compares scalar `const` schemas with their explicitly typed equivalents.\n\nReproduced against `main` at commit `833a968f84b4b0ec7c2f3fb5bb119e3c449f7a4f` (`v2.8.1-0.20260924063949-833a968f84b4`). The scalar reproduction below also fails on the latest release, `v2.8.0`.\n\nSave as `spec.yaml`:\n\n```yaml\nopenapi: 3.1.0\ninfo:\n title: Scalar const inference reproduction\n version: \"1\"\npaths: {}\ncomponents:\n schemas:\n StringConst:\n const: active\n TypedStringConst:\n type: string\n const: active\n\n IntegerConst:\n const: 0\n TypedIntegerConst:\n type: integer\n const: 0\n\n BooleanConst:\n const: false\n TypedBooleanConst:\n type: boolean\n const: false\n\n NumberConst:\n const: 1.5\n TypedNumberConst:\n type: number\n const: 1.5\n```\n\nSave as `config.yaml`:\n\n```yaml\npackage: repro\noutput: types.gen.go\ngenerate:\n models: true\noutput-options:\n skip-prune: true\n```\n\n`skip-prune: true` retains the unreferenced schemas. Other settings use their defaults.\n\nRun in a directory containing those two files:\n\n```sh\ngo run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@833a968f84b4b0ec7c2f3fb5bb119e3c449f7a4f \\\n --config=config.yaml spec.yaml\n```\n\nGeneration succeeds, but produces different representations for each equivalent pair:\n\n| Constant | Without explicit `type` | With explicit `type` |\n| --- | --- | --- |\n| `active` | `type StringConst = any` | `type TypedStringConst string` |\n| `0` | `type IntegerConst = any` | `type TypedIntegerConst int` |\n| `false` | `type BooleanConst = any` | `type TypedBooleanConst bool` |\n| `1.5` | `type NumberConst = any` | `type TypedNumberConst float32` |\n\nOnly the explicitly typed schemas receive enum constants and `Valid()` methods.\n\nOn `v2.8.0`, the untyped schemas generate `interface{}` instead of `any`; the typed controls behave as above.\n\nAdditional checks with the scalar reproduction on the pinned `main` commit:\n\n- Explicit `compatibility.schema-merging-behavior: v1`, `v2`, and experimental `v3`: same result as the default configuration.\n- `output-options.skip-enum-via-oneof: true`: same result.\n- `output-options.skip-enum-validate: true`: untyped schemas still generate `any`; the typed controls retain their scalar types and constants, with `Valid()` methods disabled as expected.\n- Setting `output-options.type-mapping.number.default.type: float64` changes `TypedNumberConst` to `float64`, while `NumberConst` remains `any`.\n- Changing the document version to `openapi: 3.1.1`: same result.\n\nExpected: scalar `const` schemas should receive the same typing and singleton-enum support as their explicitly typed counterparts, respecting configured Go type mappings.\n\nNon-scalar constraints may not be expressible through Go types alone, but scalars already have supported representations.\n\nUnder OpenAPI 3.1's JSON Schema semantics, `const` requires equality with the specified value. Adding `type` to the scalar examples above does not change which values they accept. [OpenAPI Schema Object](https://spec.openapis.org/oas/v3.1.1.html#schema-object), [JSON Schema `const`](https://json-schema.org/draft/2020-12/json-schema-validation#section-6.1.3).\n\nThe same behavior occurs inside object properties: a property containing only `const: active` becomes an `any` field.\n\nIn `generateGoSchema`, a missing `type` reaches the generic-schema branch, which selects `any` and returns before the scalar `const`/enum handler. [Generic-schema branch](https://github.com/oapi-codegen/oapi-codegen/blob/833a968f84b4b0ec7c2f3fb5bb119e3c449f7a4f/pkg/codegen/schema.go#L1272-L1293), [`const`/enum handler](https://github.com/oapi-codegen/oapi-codegen/blob/833a968f84b4b0ec7c2f3fb5bb119e3c449f7a4f/pkg/codegen/schema.go#L1476-L1506).\n\nRelated: [#2520](https://github.com/oapi-codegen/oapi-codegen/pull/2520) added inference for the `oneOf` + `title` + `const` pattern. This report concerns standalone `const` schemas without `type` and reproduces after that change.\n\nThe reproduction is provided under Apache-2.0.\n","author":{"url":"https://github.com/g-logunov","@type":"Person","name":"g-logunov"},"datePublished":"2026-09-24T14:30:59Z","url":"https://github.com/oapi-codegen/oapi-codegen/issues/2567"}
| react-profiling | 0 |
| react-import-map | react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf |
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:5f4496a9-dd6c-fd20-5179-52f0875c403c |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E870:3E754C:27D4BD5:34E2FF4:6AF9BAC2 |
| html-safe-nonce | 7e87933753b5d7407139efe1d6c74934618bec48bfce29180708dec403ce1827 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFODcwOjNFNzU0QzoyN0Q0QkQ1OjM0RTJGRjQ6NkFGOUJBQzIiLCJ2aXNpdG9yX2lkIjoiMjI5NzQ1Nzc3ODg1MjczOTc3OCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | c2acb2f49bf55aeb77de99370498b3c570800190e7a855ab4635c1d3d8995080 |
| hovercard-subject-tag | issue:5569910627 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/oapi-codegen/oapi-codegen/2567/issue_layout |
| twitter:image | https://opengraph.githubassets.com/576d19008108133f4ab31605bc06b74e2194802bfbe06e22eedb6fb99b55827b/oapi-codegen/oapi-codegen/issues/2567 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/576d19008108133f4ab31605bc06b74e2194802bfbe06e22eedb6fb99b55827b/oapi-codegen/oapi-codegen/issues/2567 |
| og:image:alt | A schema containing only const, without an explicit type, generates an alias to any. This affects all constants: scalars, arrays and objects. The reproduction below compares scalar const schemas wi... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | g-logunov |
| hostname | github.com |
| expected-hostname | github.com |
| None | 612d3e6ffd693e7ea8d9fcf452370995872baef31d825b1fedef704cd3d24ac7 |
| turbo-cache-control | no-preview |
| go-import | github.com/oapi-codegen/oapi-codegen git https://github.com/oapi-codegen/oapi-codegen.git |
| octolytics-dimension-user_id | 142752710 |
| octolytics-dimension-user_login | oapi-codegen |
| octolytics-dimension-repository_id | 173009358 |
| octolytics-dimension-repository_nwo | oapi-codegen/oapi-codegen |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 173009358 |
| octolytics-dimension-repository_network_root_nwo | oapi-codegen/oapi-codegen |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 072e34035c13c31543fba9f025cbbbda4210dae4 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
| react-app-name | issues |
Links:
Viewport: width=device-width