diff --git a/server/src/channels/routes.ts b/server/src/channels/routes.ts index c481e17a2..342317c6e 100644 --- a/server/src/channels/routes.ts +++ b/server/src/channels/routes.ts @@ -935,6 +935,12 @@ export function parseActivityInput( if (object.agentId !== null && typeof object.agentId !== "string") { return { ok: false, error: "Agent ID must be a string or null." }; } + if ( + typeof object.agentId === "string" && + object.agentId.trim().length === 0 + ) { + return { ok: false, error: "Agent ID must be a string or null." }; + } if (typeof object.at !== "string") { return { ok: false, error: "Timestamp is required." }; } diff --git a/server/tests/channel-activity-input.test.ts b/server/tests/channel-activity-input.test.ts index 88f249178..75f5aeb9f 100644 --- a/server/tests/channel-activity-input.test.ts +++ b/server/tests/channel-activity-input.test.ts @@ -52,4 +52,17 @@ describe("parsing a reported message", () => { expect(parsed.value.text).toBe("hello"); expect(parsed.value.agentId).toBe("agent-1"); }); + + test("refuses a whitespace-only agent ID rather than looking it up", () => { + // " " used to trim to "" and fall through to a 404 "Agent not found"; + // a malformed field is a 400 naming the field. + const parsed = parseActivityInput( + { text: "hello", agentId: " ", at: "2026-09-03T09:00:00.000Z" }, + now, + ); + expect(parsed).toEqual({ + ok: false, + error: "Agent ID must be a string or null.", + }); + }); });