mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-03 05:45:04 +03:00
fix(sse): remove dead-code flag leak in claudeCodeToolRemapper
remapToolNamesInRequest() set body._claudeCodeRequiresLowercaseToolNames = true when a request contained only lowercase tool names. The flag had no readers in src/ or open-sse/ (verified by repo-wide grep) and leaked into the outgoing Anthropic /v1/messages payload, causing HTTP 400: "_claudeCodeRequiresLowercaseToolNames: Extra inputs are not permitted" The response-side lowercase remap via remapToolNamesInResponse(text, true) is unconditional and does not depend on this flag, so removing it is a no-op for the response path while fixing the request path. Adds tests/unit/claude-code-tool-remapper-flag-leak.test.ts as a regression guard with 5 cases covering all-lowercase, all-TitleCase, mixed-case, and a flag-leak sweep across all input shapes.
This commit is contained in:
@@ -88,9 +88,12 @@ export function remapToolNamesInRequest(body: Record<string, unknown>): boolean
|
||||
}
|
||||
}
|
||||
|
||||
if (hasLowercase && !hasTitleCase) {
|
||||
body._claudeCodeRequiresLowercaseToolNames = true;
|
||||
}
|
||||
// NOTE: previously set body._claudeCodeRequiresLowercaseToolNames = true here.
|
||||
// Removed: the flag had no readers in the codebase and leaked into the
|
||||
// outgoing Anthropic request body, causing HTTP 400
|
||||
// "_claudeCodeRequiresLowercaseToolNames: Extra inputs are not permitted".
|
||||
// The response-side lowercase remap is unconditional anyway via
|
||||
// remapToolNamesInResponse(text, forceLowercase=true).
|
||||
|
||||
return hasLowercase && !hasTitleCase;
|
||||
}
|
||||
|
||||
59
tests/unit/claude-code-tool-remapper-flag-leak.test.ts
Normal file
59
tests/unit/claude-code-tool-remapper-flag-leak.test.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Regression test for the _claudeCodeRequiresLowercaseToolNames flag leak
|
||||
* that caused HTTP 400 "Extra inputs are not permitted" from Anthropic.
|
||||
*
|
||||
* The flag had no readers in the codebase but was assigned to the outgoing
|
||||
* request body. Anthropic's strict schema validation rejected the unknown
|
||||
* field. This test guards against re-introduction.
|
||||
*/
|
||||
import { describe, it } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { remapToolNamesInRequest } from "../../open-sse/services/claudeCodeToolRemapper.ts";
|
||||
|
||||
describe("remapToolNamesInRequest — flag-leak regression", () => {
|
||||
it("does NOT add _claudeCodeRequiresLowercaseToolNames when all tools are lowercase", () => {
|
||||
const body: Record<string, unknown> = {
|
||||
tools: [{ name: "bash" }, { name: "read" }, { name: "edit" }],
|
||||
};
|
||||
remapToolNamesInRequest(body);
|
||||
assert.equal(
|
||||
"_claudeCodeRequiresLowercaseToolNames" in body,
|
||||
false,
|
||||
"Flag must not leak into outgoing request body"
|
||||
);
|
||||
});
|
||||
|
||||
it("returns true when only lowercase tools are present", () => {
|
||||
const body: Record<string, unknown> = { tools: [{ name: "bash" }] };
|
||||
assert.equal(remapToolNamesInRequest(body), true);
|
||||
});
|
||||
|
||||
it("returns false when only TitleCase tools are present", () => {
|
||||
const body: Record<string, unknown> = { tools: [{ name: "Bash" }] };
|
||||
assert.equal(remapToolNamesInRequest(body), false);
|
||||
});
|
||||
|
||||
it("returns false when mixed-case tools are present", () => {
|
||||
const body: Record<string, unknown> = {
|
||||
tools: [{ name: "bash" }, { name: "Read" }],
|
||||
};
|
||||
assert.equal(remapToolNamesInRequest(body), false);
|
||||
});
|
||||
|
||||
it("does NOT add flag in any of the above cases", () => {
|
||||
for (const tools of [
|
||||
[{ name: "bash" }],
|
||||
[{ name: "Bash" }],
|
||||
[{ name: "bash" }, { name: "Read" }],
|
||||
[],
|
||||
]) {
|
||||
const body: Record<string, unknown> = { tools };
|
||||
remapToolNamesInRequest(body);
|
||||
assert.equal(
|
||||
"_claudeCodeRequiresLowercaseToolNames" in body,
|
||||
false,
|
||||
`Flag leaked for tools=${JSON.stringify(tools)}`
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user