From b36362ab866cfff90c1b5db8d35057e64335789a Mon Sep 17 00:00:00 2001 From: yogeshwaran-c Date: Thu, 16 Apr 2026 07:48:39 +0530 Subject: [PATCH 1/2] fix(spec): handle requestBody with no content without crashing When a requestBody object has no content property (only description and required), the requiredParameters selector would crash with TypeError: Cannot read properties of undefined (reading 'entrySeq') because requestBody.getIn(["content"]) returns undefined. This adds a null check before iterating over content entries, returning the partial result early when content is absent. Fixes #10767 --- src/core/plugins/spec/selectors.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/plugins/spec/selectors.js b/src/core/plugins/spec/selectors.js index f8580156333..35842823ba1 100644 --- a/src/core/plugins/spec/selectors.js +++ b/src/core/plugins/spec/selectors.js @@ -546,7 +546,11 @@ export const getOAS3RequiredRequestBodyContentType = (state, pathMethod) => { if (requestBody.getIn(["required"])) { requiredObj.requestBody = requestBody.getIn(["required"]) } - requestBody.getIn(["content"]).entrySeq().forEach((contentType) => { // e.g application/json + const requestBodyContent = requestBody.getIn(["content"]) + if (!requestBodyContent) { + return requiredObj + } + requestBodyContent.entrySeq().forEach((contentType) => { // e.g application/json const key = contentType[0] if (contentType[1].getIn(["schema", "required"])) { const val = contentType[1].getIn(["schema", "required"]).toJS() From 9aa59402f905bc88558866b0b12e073e39b151f0 Mon Sep 17 00:00:00 2001 From: yogeshwaran-c Date: Thu, 16 Apr 2026 20:41:33 +0530 Subject: [PATCH 2/2] test(spec): add coverage for getOAS3RequiredRequestBodyContentType Cover the case where requestBody has no content property to prevent regression of the no-content crash fix. --- test/unit/core/plugins/spec/selectors.js | 78 ++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test/unit/core/plugins/spec/selectors.js b/test/unit/core/plugins/spec/selectors.js index 53df1c71d8a..672c87baca0 100644 --- a/test/unit/core/plugins/spec/selectors.js +++ b/test/unit/core/plugins/spec/selectors.js @@ -15,6 +15,7 @@ import { consumesOptionsFor, taggedOperations, isMediaTypeSchemaPropertiesEqual, + getOAS3RequiredRequestBodyContentType, validationErrors } from "core/plugins/spec/selectors" @@ -1239,6 +1240,83 @@ describe("taggedOperations", function () { expect(result.toJS()).toEqual([]) }) }) +describe("getOAS3RequiredRequestBodyContentType", () => { + const pathMethod = ["/test", "post"] + + it("should return default requiredObj when requestBody is missing", () => { + const state = fromJS({ + resolvedSubtrees: { + paths: { + "/test": { + post: {} + } + } + } + }) + + const result = getOAS3RequiredRequestBodyContentType(state, pathMethod) + + expect(result).toEqual({ + requestBody: false, + requestContentType: {} + }) + }) + + it("should not crash and return requiredObj when requestBody has no content", () => { + const state = fromJS({ + resolvedSubtrees: { + paths: { + "/test": { + post: { + requestBody: { + required: true + } + } + } + } + } + }) + + const result = getOAS3RequiredRequestBodyContentType(state, pathMethod) + + expect(result).toEqual({ + requestBody: true, + requestContentType: {} + }) + }) + + it("should collect required schema fields per content type when content is present", () => { + const state = fromJS({ + resolvedSubtrees: { + paths: { + "/test": { + post: { + requestBody: { + required: true, + content: { + "application/json": { + schema: { + required: ["name", "email"] + } + } + } + } + } + } + } + } + }) + + const result = getOAS3RequiredRequestBodyContentType(state, pathMethod) + + expect(result).toEqual({ + requestBody: true, + requestContentType: { + "application/json": ["name", "email"] + } + }) + }) +}) describe("isMediaTypeSchemaPropertiesEqual", () => { const stateSingleMediaType = fromJS({ resolvedSubtrees: {