{"record":{"id":"adc5a4106e82d437","repo":"Mintplex-Labs/anything-llm","slug":"message-is-empty-adc5a4","errorCode":null,"errorMessage":"Message is empty.","messagePattern":"Message is empty\\.","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"server/endpoints/chat.js","lineNumber":33,"sourceCode":"const { writeResponseChunk } = require(\"../utils/helpers/chat/responses\");\nconst { WorkspaceThread } = require(\"../models/workspaceThread\");\nconst { User } = require(\"../models/user\");\nconst { getModelTag } = require(\"./utils\");\n\nfunction chatEndpoints(app) {\n  if (!app) return;\n\n  app.post(\n    \"/workspace/:slug/stream-chat\",\n    [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],\n    async (request, response) => {\n      try {\n        const user = await userFromSession(request, response);\n        const { message, attachments = [] } = reqBody(request);\n        const workspace = response.locals.workspace;\n\n        if (typeof message !== \"string\" || message.trim().length === 0) {\n          response.status(400).json({\n            id: uuidv4(),\n            type: \"abort\",\n            textResponse: null,\n            sources: [],\n            close: true,\n            error: \"Message is empty.\",\n          });\n          return;\n        }\n\n        response.setHeader(\"Cache-Control\", \"no-cache\");\n        response.setHeader(\"Content-Type\", \"text/event-stream\");\n        response.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n        response.setHeader(\"Connection\", \"keep-alive\");\n        response.flushHeaders();\n\n        if (multiUserMode(response) && !(await User.canSendChat(user))) {\n          writeResponseChunk(response, {","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/endpoints/chat.js#L15-L51","documentation":"Deliberate 400 from POST /workspace/:slug/stream-chat when `message` is not a string or is empty/whitespace-only. The check runs before the SSE stream opens, and the 400 body is shaped like an abort event (id/type/close) so streaming clients terminate cleanly. Identical validation exists on the thread variant of the route.","triggerScenarios":"message missing from the JSON body; message sent as a number, object, or null (fails typeof check); message is \"\" or \"   \"; attachments-only POST with no message field.","commonSituations":"Frontend firing the request before input state populates; automated/API clients omitting message; whitespace-only input that only gets trimmed server-side.","solutions":["Send `message` as a non-empty, trimmed string in the JSON body.","If you intended an attachments-only turn, note the API still requires a non-empty message - add accompanying text.","Guard client-side before POSTing (see exampleFix)."],"exampleFix":"// before\nfetch(`/workspace/${slug}/stream-chat`, { method: \"POST\", body: JSON.stringify({ message: input.value, attachments }) });\n// after\nconst message = input.value.trim();\nif (!message) return showError(\"Type a message first\");\nfetch(`/workspace/${slug}/stream-chat`, { method: \"POST\", body: JSON.stringify({ message, attachments }) });","handlingStrategy":"validation","validationCode":"const message = typeof rawMessage === 'string' ? rawMessage.trim() : '';\nif (!message) throw new Error('Refusing to send: message is empty');\nawait streamChat(slug, { message, attachments });","typeGuard":"const isNonEmptyMessage = (m: unknown): m is string =>\n  typeof m === 'string' && m.trim().length > 0;","tryCatchPattern":null,"preventionTips":["Disable the send button until the composer has non-whitespace text.","Trim input client-side so server-side trimming can never surprise you.","Remember attachments do not replace the required message field."],"tags":["chat","http-400","validation","streaming"],"backgroundTag":"request-validation-failed","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}