fix(gateway): reject empty embedding inputs before provider setup (#117615)

Co-authored-by: Peter Steinberger <steipete@macos.shared>
This commit is contained in:
Peter Steinberger
2026-08-01 14:04:36 -07:00
committed by GitHub
parent 813b7975aa
commit e19486d023
2 changed files with 30 additions and 0 deletions

View File

@@ -434,6 +434,33 @@ describe("OpenAI-compatible embeddings HTTP API (e2e)", () => {
await expectInvalidEmbeddingRequest(res);
});
it.each([
{ name: "an empty string", input: "" },
{ name: "an empty batch", input: [] },
{ name: "an empty batch entry", input: [""] },
{ name: "a mixed batch with an empty entry", input: ["valid", ""] },
])("rejects $name before creating an embedding provider", async ({ input }) => {
const providersCreatedBefore = createEmbeddingProviderMock.mock.calls.length;
const res = await postEmbeddings({
model: "openclaw/default",
input,
});
await expectInvalidEmbeddingRequest(res, "`input` must contain at least one non-empty string.");
expect(createEmbeddingProviderMock).toHaveBeenCalledTimes(providersCreatedBefore);
});
it("preserves whitespace-only embedding input", async () => {
const input = " \t\n";
const res = await postEmbeddings({
model: "openclaw/default",
input,
});
await expectDefaultEmbeddingResponse(res);
expect(embedBatchMock.mock.calls.at(-1)?.[0]).toEqual([input]);
});
it("ignores narrower declared scopes for shared-secret bearer auth", async () => {
const res = await postEmbeddings(
{

View File

@@ -200,6 +200,9 @@ function encodeEmbeddingBase64(embedding: number[]): string {
// Keep request limits local to the HTTP bridge; provider adapters may support
// more, but this endpoint must protect gateway memory and request latency.
function validateInputTexts(texts: string[]): string | undefined {
if (texts.length === 0 || texts.some((text) => text.length === 0)) {
return "`input` must contain at least one non-empty string.";
}
if (texts.length > MAX_EMBEDDING_INPUTS) {
return `Too many inputs (max ${MAX_EMBEDDING_INPUTS}).`;
}