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

  1. Ensure the messageId is created and non-empty before invoking createChunkProcessor.
  2. Persist the message first, then start the chunk processor with the resulting id.
  3. 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

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


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/adb950138ca9b052. Report an issue: GitHub.