danny-avila/LibreChat · error
Message ID is required
Error message
Message ID is required
What it means
createChunkProcessor requires a messageId up front because it builds the messages-cache key (scopedCacheKey(messageId)) used to poll streaming TTS chunks. It throws synchronously at construction time, before any async work, since without an id there is nothing to poll. This is a programmer/contract error, not a user input error.
Source
Thrown at api/server/services/Files/Audio/streamAudio.js:67
* @property {number[]} normalizedAlignment.char_start_times_ms
* @property {number[]} normalizedAlignment.chars_durations_ms
* @property {string[]} normalizedAlignment.chars
*/
const MAX_NOT_FOUND_COUNT = 6;
const MAX_NO_CHANGE_COUNT = 10;
/**
* @param {string} user
* @param {string} messageId
* @returns {() => Promise<{ text: string, isFinished: boolean }[]>}
*/
function createChunkProcessor(user, messageId) {
let notFoundCount = 0;
let noChangeCount = 0;
let processedText = '';
if (!messageId) {
throw new Error('Message ID is required');
}
const messageCache = getLogStores(CacheKeys.MESSAGES);
// Captured at creation time — must be called within an active request ALS scope
const cacheKey = scopedCacheKey(messageId);
/**
* @returns {Promise<{ text: string, isFinished: boolean }[] | string>}
*/
async function processChunks() {
if (notFoundCount >= MAX_NOT_FOUND_COUNT) {
return `Message not found after ${MAX_NOT_FOUND_COUNT} attempts`;
}
if (noChangeCount >= MAX_NO_CHANGE_COUNT) {
return `No change in message after ${MAX_NO_CHANGE_COUNT} attempts`;
}
View on GitHub (pinned to 5ff282f900)
Solutions
- Ensure the messageId is created and non-empty before invoking createChunkProcessor.
- Persist the message first, then start the chunk processor with the resulting id.
- Add a caller-side guard so an absent id short-circuits before reaching this function.
Example fix
// before
const processor = createChunkProcessor(user, req.body.messageId);
// after
if (!req.body.messageId) {
return res.status(400).json({ error: 'messageId is required' });
}
const processor = createChunkProcessor(user, req.body.messageId); Defensive patterns
Strategy: validation
Validate before calling
if (!messageId || typeof messageId !== 'string') {
throw new Error('messageId must be a non-empty string');
}
const processor = createChunkProcessor(user, messageId); Type guard
/** @param {unknown} id */
function isValidMessageId(id) {
return typeof id === 'string' && id.length > 0;
} Prevention
- Persist the message and obtain its id before starting the chunk processor.
- Validate the request payload's messageId at the route boundary.
- Treat a missing id as a 400, not as something to retry.
When it happens
Trigger: A caller invokes createChunkProcessor(user, messageId) with messageId undefined, null, or empty string — typically because the message had not been persisted yet or the request payload omitted the id.
Common situations: TTS streaming initiated before the parent message was saved; frontend request missing the messageId field; race where message creation hasn't resolved; refactor that dropped the argument.
Related errors
- No download stream method found for source: ${source}
- Failed to get download stream for image file
- No TTS schema is set. Did you configure TTS in the custom co
- Multiple providers are set. Please set only one provider.
- No provider is set. Please set a provider.
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/adb950138ca9b052.
Report an issue: GitHub.