mastra-ai/mastra · warning · StaleKnowledgeSemanticIndexError

Knowledge semantic index is stale because operation ${entry.

Error message

Knowledge semantic index is stale because operation ${entry.id} could not be applied.

What it means

Inside `#drain` (semantic-index.ts:144), if applying an outbox operation (`#apply`) throws — e.g. embedding or vector-store failure — the worker releases all remaining entries back to 'pending' (so another worker can retry) and throws `StaleKnowledgeSemanticIndexError` with the original error as `cause`, signaling the index could not be brought up to date.

Source

Thrown at packages/memory/src/processors/observational-memory/subconscious/semantic-index.ts:144

          throw new StaleKnowledgeSemanticIndexError(
            'Knowledge semantic index is stale: a visible operation is pending or being processed by another worker.',
          );
        }
        return processed;
      }

      for (let index = 0; index < entries.length; index++) {
        const entry = entries[index]!;
        try {
          await this.#apply(entry);
          await this.#knowledge.completeSemanticOutbox({ ids: [entry.id], workerId: this.#workerId });
          processed++;
        } catch (error) {
          await this.#knowledge.releaseSemanticOutbox({
            ids: entries.slice(index).map(pendingEntry => pendingEntry.id),
            workerId: this.#workerId,
          });
          throw new StaleKnowledgeSemanticIndexError(
            `Knowledge semantic index is stale because operation ${entry.id} could not be applied.`,
            { cause: error },
          );
        }
      }
    }
    throw new StaleKnowledgeSemanticIndexError(
      `Knowledge semantic index remained stale after ${MAX_DRAIN_BATCHES} processing batches.`,
    );
  }

  async #apply(entry: KnowledgeSemanticOutboxEntry): Promise<void> {
    if (entry.operation === 'delete') {
      await this.#deleteDocument(entry.documentId);
      return;
    }

    const document = await this.#loadDocument(entry);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Inspect `error.cause` for the underlying embedder/vector-store failure and fix it (credentials, rate limits, payload size).
  2. Retry — the failed entries were released back to 'pending', so a subsequent drain can reprocess them.
  3. Add idempotent retry/backoff in your indexing worker; validate outbox entries before applying.

Example fix

// before
await remind(context); // StaleKnowledgeSemanticIndexError, cause hidden
// after
try {
  await remind(context);
} catch (e) {
  if (e instanceof StaleKnowledgeSemanticIndexError && e.cause) {
    console.error('underlying cause:', e.cause); // fix root cause, then retry
  }
  throw e;
}
Defensive patterns

Strategy: retry

Try / catch

try {
  return await remind(context);
} catch (e) {
  if (e instanceof StaleKnowledgeSemanticIndexError && e.cause) {
    logger.error('outbox apply failed', { cause: e.cause });
    await new Promise((r) => setTimeout(r, 2000));
    return remind(context); // entries were released back to pending
  }
  throw e;
}

Prevention

When it happens

Trigger: `#apply(entry)` rejects while draining: embedder API error on the document text, vector store insert/delete failure, index creation failure, or malformed outbox entry (e.g. missing document text).

Common situations: Embedding provider rate limits or outages during indexing; vector DB connection issues; oversized documents exceeding embedder limits; corrupted outbox rows after a partial migration.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/2ff79f873d47aaa0. Report an issue: GitHub.