From e1ed5f3ac018ef3f4bcca3653fd2fd1e2dd761c1 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Thu, 8 Jan 2026 09:09:06 -0500 Subject: [PATCH 1/2] Fix statusCode defined in base model with empty self --- packages/http/src/http-property.ts | 2 +- packages/http/test/responses.test.ts | 31 +++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/http/src/http-property.ts b/packages/http/src/http-property.ts index c90bf389766..ca3be460b9c 100644 --- a/packages/http/src/http-property.ts +++ b/packages/http/src/http-property.ts @@ -240,7 +240,7 @@ export function resolvePayloadProperties( const diagnostics = createDiagnosticCollector(); const httpProperties = new Map(); - if (type.kind !== "Model" || type.properties.size === 0) { + if (type.kind !== "Model" || (type.properties.size === 0 && !type.baseModel)) { return diagnostics.wrap([]); } diff --git a/packages/http/test/responses.test.ts b/packages/http/test/responses.test.ts index b5b79787459..967f36bc519 100644 --- a/packages/http/test/responses.test.ts +++ b/packages/http/test/responses.test.ts @@ -1,7 +1,7 @@ import type { Model } from "@typespec/compiler"; import { expectDiagnosticEmpty, expectDiagnostics } from "@typespec/compiler/testing"; import { deepStrictEqual, ok, strictEqual } from "assert"; -import { describe, it } from "vitest"; +import { describe, expect, it } from "vitest"; import { compileOperations, getOperationsWithServiceNamespace } from "./test-host.js"; describe("body resolution", () => { @@ -214,3 +214,32 @@ it("chooses correct content-type for extensible union body", async () => { ok(body); deepStrictEqual(body.contentTypes, ["text/plain"]); }); + +describe("status code", () => { + async function getResponse(code: string) { + const [routes, diagnostics] = await getOperationsWithServiceNamespace(code); + expectDiagnosticEmpty(diagnostics); + expect(routes).toHaveLength(1); + expect(routes[0].responses).toHaveLength(1); + return routes[0].responses[0]; + } + + it("resolve from a property at the root", async () => { + const response = await getResponse(`op test1(): { @statusCode code: 201 };`); + expect(response.statusCodes).toEqual(201); + }); + + it("resolve from a property nested", async () => { + const response = await getResponse(`op test1(): { nested: { @statusCode code: 201 } };`); + expect(response.statusCodes).toEqual(201); + }); + + it("resolve from parent model with no local props", async () => { + const response = await getResponse(` + model Created { @statusCode code: 201 } + model Res extends Created {}; + op test1(): Res; + `); + expect(response.statusCodes).toEqual(201); + }); +}); From 702d32685a9b235d0679f893df717908617c38d2 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Thu, 8 Jan 2026 06:13:55 -0800 Subject: [PATCH 2/2] Create fix-status-code-from-base-model-2026-0-8-14-10-21.md --- .../fix-status-code-from-base-model-2026-0-8-14-10-21.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .chronus/changes/fix-status-code-from-base-model-2026-0-8-14-10-21.md diff --git a/.chronus/changes/fix-status-code-from-base-model-2026-0-8-14-10-21.md b/.chronus/changes/fix-status-code-from-base-model-2026-0-8-14-10-21.md new file mode 100644 index 00000000000..913e799d5b9 --- /dev/null +++ b/.chronus/changes/fix-status-code-from-base-model-2026-0-8-14-10-21.md @@ -0,0 +1,8 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: fix +packages: + - "@typespec/http" +--- + +Fix empty response models with `statusCode` defined in a base model