TencentCloud/TencentDB-Agent-Memory · error · EmbeddingNotReadyError

Local embedding model warmup has not been started. Call star

Error message

Local embedding model warmup has not been started. Call startWarmup() first.

What it means

assertReady() throws EmbeddingNotReadyError when initState is 'idle' — startWarmup() was never called on this local embedder instance, so no model has been loaded and embeddingContext is null. The local provider requires an explicit warmup step before embed()/embedBatch() can be used.

Source

Thrown at MemoryCore/src/core/store/embedding.ts:295

   * Assert the model is ready. Throws EmbeddingNotReadyError if not.
   */
  private assertReady(): void {
    if (this.initState === "ready" && this.embeddingContext) {
      return;
    }
    if (this.initState === "failed") {
      throw new EmbeddingNotReadyError(
        `Local embedding model initialization failed: ${this.initError?.message ?? "unknown error"}. ` +
        `Call startWarmup() to retry.`,
      );
    }
    if (this.initState === "initializing") {
      throw new EmbeddingNotReadyError(
        "Local embedding model is still loading (download/initialization in progress). Please try again later.",
      );
    }
    // "idle" — startWarmup() was never called
    throw new EmbeddingNotReadyError(
      "Local embedding model warmup has not been started. Call startWarmup() first.",
    );
  }

  /**
   * Truncate input text to stay within the model's context window.
   * embeddinggemma-300m has a 256-token limit; we use a character-based
   * heuristic (LOCAL_MAX_INPUT_CHARS) as a safe proxy.
   */
  private truncateInput(text: string): string {
    if (text.length <= LOCAL_MAX_INPUT_CHARS) return text;
    this.logger?.debug?.(
      `${TAG} Input truncated from ${text.length} to ${LOCAL_MAX_INPUT_CHARS} chars (model context limit)`,
    );
    return text.slice(0, LOCAL_MAX_INPUT_CHARS);
  }

  /**

View on GitHub (pinned to 3efcd317b8)

Solutions

  1. Call startWarmup() once during application startup (and await it) before any embed/embedBatch usage.
  2. If the embedder was closed (close() sets state back to 'idle'), call startWarmup() again before further embed calls.
  3. Lazily invoke startWarmup() on first embed if your wrapper allows it, so the state machine always passes through warmup.

Example fix

// before
const embedder = new LocalEmbedder(opts);
const vec = await embedder.embed(text); // state 'idle' -> throws
// after
const embedder = new LocalEmbedder(opts);
await embedder.startWarmup();
const vec = await embedder.embed(text);
Defensive patterns

Strategy: try-catch

Validate before calling

if ((embedder as any).initState === "idle") {
  await embedder.startWarmup();
}

Type guard

function isEmbeddingNotReadyError(e: unknown): e is EmbeddingNotReadyError {
  return e instanceof EmbeddingNotReadyError;
}

Try / catch

try {
  return await embedder.embed(text);
} catch (e) {
  if (isEmbeddingNotReadyError(e) && /has not been started/.test(e.message)) {
    await embedder.startWarmup();
    return await embedder.embed(text);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling embed() or embedBatch() on a freshly constructed local embedder without ever calling startWarmup(); also after close() resets state to 'idle' and embed is called without re-warming.

Common situations: New integration where the initialization step was skipped or reordered (constructor used directly instead of an init flow); a refactor moved startWarmup() out of the startup path; calling embed after close()/dispose without re-initializing; example code copied omitting the warmup call.

Related errors


AI-assisted analysis of TencentCloud/TencentDB-Agent-Memory@3efcd317b8 (2026-09-01). Data as JSON: /api/errors/96c5114841d91727. Report an issue: GitHub.