Skip to content

Instantly share code, notes, and snippets.

@nrutman
Created May 20, 2026 18:58
Show Gist options
  • Select an option

  • Save nrutman/a4b4605164938dbd055040c89976c829 to your computer and use it in GitHub Desktop.

Select an option

Save nrutman/a4b4605164938dbd055040c89976c829 to your computer and use it in GitHub Desktop.
Minimum repro: @nestjs/swagger 11.4.3 emits contradictory type: object with oneOf + nullable: true

@nestjs/swagger 11.4.3 — oneOf + nullable: true produces contradictory type: object

Minimum repro for the bug described in the linked issue.

Code

// dto.ts
import { ApiProperty } from "@nestjs/swagger";

export type CellValue = string | number | null;

export class Cell {
  @ApiProperty({
    oneOf: [{ type: "string" }, { type: "number" }],
    nullable: true,
  })
  value!: CellValue;
}
// main.ts
import { NestFactory } from "@nestjs/core";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { Module } from "@nestjs/common";
import { Cell } from "./dto";

@Module({})
class AppModule {}

async function main() {
  const app = await NestFactory.create(AppModule, { logger: false });
  const doc = SwaggerModule.createDocument(
    app,
    new DocumentBuilder().build(),
    { extraModels: [Cell] },
  );
  console.log(JSON.stringify(doc.components?.schemas?.Cell, null, 2));
  await app.close();
}

main();

package.json

{
  "name": "swagger-oneof-nullable-repro",
  "type": "module",
  "scripts": { "start": "ts-node main.ts" },
  "dependencies": {
    "@nestjs/common": "^11.1.20",
    "@nestjs/core": "^11.1.20",
    "@nestjs/swagger": "11.4.3",
    "reflect-metadata": "^0.2.2",
    "rxjs": "^7.8.2"
  },
  "devDependencies": {
    "ts-node": "^10.9.1",
    "typescript": "^5.9.3"
  }
}

Steps

  1. pnpm install
  2. pnpm start

Observed output

{
  "type": "object",
  "properties": {
    "value": {
      "type": "object",
      "oneOf": [
        { "type": "string" },
        { "type": "number" }
      ],
      "nullable": true
    }
  },
  "required": ["value"]
}

The value schema is contradictory: type: "object" requires the value to be an object, while oneOf only permits primitives. Spectral (oas3-schema) flags this. Generated SDK clients refuse all valid payloads.

Expected output

{
  "type": "object",
  "properties": {
    "value": {
      "oneOf": [
        { "type": "string" },
        { "type": "number" }
      ],
      "nullable": true
    }
  },
  "required": ["value"]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment