Mintplex-Labs/anything-llm · warning

Message is empty.

Error message

Message is empty.

What it means

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.

Source

Thrown at server/endpoints/chat.js:33

const { writeResponseChunk } = require("../utils/helpers/chat/responses");
const { WorkspaceThread } = require("../models/workspaceThread");
const { User } = require("../models/user");
const { getModelTag } = require("./utils");

function chatEndpoints(app) {
  if (!app) return;

  app.post(
    "/workspace/:slug/stream-chat",
    [validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
    async (request, response) => {
      try {
        const user = await userFromSession(request, response);
        const { message, attachments = [] } = reqBody(request);
        const workspace = response.locals.workspace;

        if (typeof message !== "string" || message.trim().length === 0) {
          response.status(400).json({
            id: uuidv4(),
            type: "abort",
            textResponse: null,
            sources: [],
            close: true,
            error: "Message is empty.",
          });
          return;
        }

        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Content-Type", "text/event-stream");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Connection", "keep-alive");
        response.flushHeaders();

        if (multiUserMode(response) && !(await User.canSendChat(user))) {
          writeResponseChunk(response, {

View on GitHub (pinned to 3aec848f28)

Solutions

  1. Send `message` as a non-empty, trimmed string in the JSON body.
  2. If you intended an attachments-only turn, note the API still requires a non-empty message - add accompanying text.
  3. Guard client-side before POSTing (see exampleFix).

Example fix

// before
fetch(`/workspace/${slug}/stream-chat`, { method: "POST", body: JSON.stringify({ message: input.value, attachments }) });
// after
const message = input.value.trim();
if (!message) return showError("Type a message first");
fetch(`/workspace/${slug}/stream-chat`, { method: "POST", body: JSON.stringify({ message, attachments }) });
Defensive patterns

Strategy: validation

Validate before calling

const message = typeof rawMessage === 'string' ? rawMessage.trim() : '';
if (!message) throw new Error('Refusing to send: message is empty');
await streamChat(slug, { message, attachments });

Type guard

const isNonEmptyMessage = (m: unknown): m is string =>
  typeof m === 'string' && m.trim().length > 0;

Prevention

When it happens

Trigger: 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.

Common situations: Frontend firing the request before input state populates; automated/API clients omitting message; whitespace-only input that only gets trimmed server-side.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18). Data as JSON: /api/errors/adc5a4106e82d437. Report an issue: GitHub.