From c7a8350e8532ec7f5706d3da4b2da7e73d57a00e Mon Sep 17 00:00:00 2001 From: Maruthan G Date: Sat, 11 Apr 2026 15:24:37 +0530 Subject: [PATCH] fix(err): filter false-positive ExampleElement mutually exclusive resolver errors --- .../plugins/err/error-transformers/hook.js | 4 +- .../example-mutually-exclusive.js | 19 +++++ .../example-mutually-exclusive.js | 85 +++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/core/plugins/err/error-transformers/transformers/example-mutually-exclusive.js create mode 100644 test/unit/core/plugins/err/transformers/example-mutually-exclusive.js diff --git a/src/core/plugins/err/error-transformers/hook.js b/src/core/plugins/err/error-transformers/hook.js index e4e3ae080e3..044fdb7a7e3 100644 --- a/src/core/plugins/err/error-transformers/hook.js +++ b/src/core/plugins/err/error-transformers/hook.js @@ -1,10 +1,12 @@ import reduce from "lodash/reduce" import * as NotOfType from "./transformers/not-of-type" import * as ParameterOneOf from "./transformers/parameter-oneof" +import * as ExampleMutuallyExclusive from "./transformers/example-mutually-exclusive" const errorTransformers = [ NotOfType, - ParameterOneOf + ParameterOneOf, + ExampleMutuallyExclusive ] export default function transformErrors (errors) { diff --git a/src/core/plugins/err/error-transformers/transformers/example-mutually-exclusive.js b/src/core/plugins/err/error-transformers/transformers/example-mutually-exclusive.js new file mode 100644 index 00000000000..f8227fb2273 --- /dev/null +++ b/src/core/plugins/err/error-transformers/transformers/example-mutually-exclusive.js @@ -0,0 +1,19 @@ +export function transform(errors) { + // Filter out false-positive "mutually exclusive" errors for ExampleElement + // that occur when path-level $ref is used with examples containing externalValue. + // This is a known issue in the upstream apidom-reference library where + // the resolver incorrectly reports value and externalValue as mutually exclusive + // after resolving a path-level $ref. + // See: https://github.com/swagger-api/swagger-ui/issues/10418 + return errors.filter((err) => { + if (err.get("source") !== "resolver") { + return true + } + const message = err.get("message") || "" + return ( + message.indexOf( + "ExampleElement value and externalValue fields are mutually exclusive" + ) === -1 + ) + }) +} diff --git a/test/unit/core/plugins/err/transformers/example-mutually-exclusive.js b/test/unit/core/plugins/err/transformers/example-mutually-exclusive.js new file mode 100644 index 00000000000..3408da28e32 --- /dev/null +++ b/test/unit/core/plugins/err/transformers/example-mutually-exclusive.js @@ -0,0 +1,85 @@ +import { Map, List } from "immutable" +import { transform } from "core/plugins/err/error-transformers/transformers/example-mutually-exclusive" + +describe("err plugin - transformers - example mutually exclusive", () => { + + it("should filter out false-positive ExampleElement mutually exclusive resolver errors", () => { + let ori = List([ + Map({ + path: "post.responses.200.content.application/json.examples.testExample.externalValue", + message: "Could not resolve reference: ExampleElement value and externalValue fields are mutually exclusive.", + source: "resolver", + level: "error", + type: "thrown" + }) + ]) + + let res = transform(ori) + + expect(res.size).toEqual(0) + }) + + it("should not filter out non-resolver errors with the same message", () => { + let ori = List([ + Map({ + path: "some.path", + message: "ExampleElement value and externalValue fields are mutually exclusive.", + source: "parser", + level: "error", + type: "thrown" + }) + ]) + + let res = transform(ori) + + expect(res.size).toEqual(1) + }) + + it("should not filter out other resolver errors", () => { + let ori = List([ + Map({ + path: "some.path", + message: "Could not resolve reference: some other error", + source: "resolver", + level: "error", + type: "thrown" + }) + ]) + + let res = transform(ori) + + expect(res.size).toEqual(1) + }) + + it("should keep unrelated errors while filtering the mutually exclusive error", () => { + let ori = List([ + Map({ + path: "info.version", + message: "is not of a type(s) string", + source: "structural", + level: "error" + }), + Map({ + path: "post.responses.200.content.application/json.examples.testExample.externalValue", + message: "Could not resolve reference: ExampleElement value and externalValue fields are mutually exclusive.", + source: "resolver", + level: "error", + type: "thrown" + }), + Map({ + path: "paths./test", + message: "Could not resolve reference: Network error", + source: "resolver", + level: "error", + type: "thrown" + }) + ]) + + let res = transform(ori) + + expect(res.size).toEqual(2) + expect(res.get(0).get("message")).toEqual("is not of a type(s) string") + expect(res.get(1).get("message")).toEqual("Could not resolve reference: Network error") + }) + +})