Mintplex-Labs/anything-llm · error
Invalid session ID.
Error message
Invalid session ID.
What it means
Session validation inside canRespond: the body's sessionId must be a string and pass uuid validate(); otherwise HTTP 404 with an abort payload 'Invalid session ID.'. The 404 status (not 400) reflects that the session does not exist. Widgets are expected to generate one UUID per conversation and keep sending it for follow-ups.
Source
Thrown at server/utils/middleware/embedMiddleware.js:100
});
return;
}
if (allowedHosts !== null && !allowedHosts.includes(host)) {
response.status(401).json({
id: uuidv4(),
type: "abort",
textResponse: null,
sources: [],
close: true,
error: "Invalid request.",
});
return;
}
const { sessionId, message } = reqBody(request);
if (typeof sessionId !== "string" || !validate(String(sessionId))) {
response.status(404).json({
id: uuidv4(),
type: "abort",
textResponse: null,
sources: [],
close: true,
error: "Invalid session ID.",
});
return;
}
if (!message?.length || !VALID_CHAT_MODE.includes(embed.chat_mode)) {
response.status(400).json({
id: uuidv4(),
type: "abort",
textResponse: null,
sources: [],
close: true,
error: !message?.lengthView on GitHub (pinned to 3aec848f28)
Solutions
- Generate the session id once per conversation with crypto.randomUUID() and reuse it for all messages in that conversation
- Ensure the body field is exactly sessionId and is a string UUID
- If integrating server-side, keep the uuid with the user's conversation state (e.g. localStorage/session storage in a widget)
Example fix
// before
body: JSON.stringify({ sessionId: 'session-1', message: text }) // -> 404 Invalid session ID.
// after
const sessionId = crypto.randomUUID(); // once per conversation, then reuse
body: JSON.stringify({ sessionId, message: text }) Defensive patterns
Strategy: type-guard
Validate before calling
const { validate } = require('uuid');
const sessionId = store.get('embedSessionId') ?? crypto.randomUUID();
store.set('embedSessionId', sessionId);
if (!validate(sessionId)) throw new Error('sessionId must be a UUID'); Type guard
const isValidSessionId = (id) =>
typeof id === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
// or: const { validate } = require('uuid'); const isValidSessionId = (id) => typeof id === 'string' && validate(id); Try / catch
if (res.status === 404) {
const data = await res.json();
if (/Invalid session ID/.test(data.error ?? '')) resetSessionId(); // regenerate and retry once
} Prevention
- Create the session UUID once and persist it for the whole conversation
- Never send custom incremental ids to embed endpoints
- Guard the request builder with the UUID validator
When it happens
Trigger: POSTing a chat message with sessionId missing, null, a number, or any non-UUID string ('session-1', 'abc', a nanoid); sending an unquoted UUID in form-encoded bodies; forgetting to persist the generated id between messages so every send uses a fresh invalid value.
Common situations: Custom widget integrations that use their own incremental ids; JSON serialization dropping the field; SSR frameworks rendering the widget before the id is created.
Related errors
- Flow not found
- Message is empty.
- Your quota for this chat has been reached. Try again later o
- res.statusText
- click requires <x> <y> coordinates
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/10e420ae429e8b65.
Report an issue: GitHub.