ruvnet/ruflo · error

OpenAI embedding failed: ${message}

Error message

OpenAI embedding failed: ${message}

What it means

OpenAIEmbeddingService.embed() wraps every failure of the underlying callOpenAI() request in 'OpenAI embedding failed: <cause>'. The embedded cause text identifies the real problem: an HTTP error (auth, quota, model), a network/timeout failure (default 30s), or a malformed response. An embed_error event is emitted to registered listeners before the throw, so the failing text is observable.

Source

Thrown at v3/@claude-flow/embeddings/src/embedding-service.ts:254

      // Cache result
      this.cache.set(text, embedding);

      const latencyMs = performance.now() - startTime;
      this.emitEvent({ type: 'embed_complete', text, latencyMs });

      return {
        embedding,
        latencyMs,
        usage: {
          promptTokens: response.usage?.prompt_tokens ?? 0,
          totalTokens: response.usage?.total_tokens ?? 0,
        },
      };
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Unknown error';
      this.emitEvent({ type: 'embed_error', text, error: message });
      throw new Error(`OpenAI embedding failed: ${message}`);
    }
  }

  async embedBatch(texts: string[]): Promise<BatchEmbeddingResult> {
    this.emitEvent({ type: 'batch_start', count: texts.length });
    const startTime = performance.now();

    // Check cache for each text
    const cached: Array<{ index: number; embedding: Float32Array }> = [];
    const uncached: Array<{ index: number; text: string }> = [];

    texts.forEach((text, index) => {
      const cachedEmbedding = this.cache.get(text);
      if (cachedEmbedding) {
        cached.push({ index, embedding: cachedEmbedding });
        this.emitEvent({ type: 'cache_hit', text });
      } else {
        uncached.push({ index, text });

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Read the wrapped cause and map it: 401 → fix apiKey; model errors → fix config.model; timeout → raise config.timeout or shrink input
  2. Chunk long text before embedding (e.g. split to a few thousand tokens per call)
  3. For flaky networks, raise config.maxRetries or add call-site retry with backoff around embed()/embedBatch()

Example fix

// before
const svc = new OpenAIEmbeddingService({ apiKey: '' });
await svc.embed('hello'); // OpenAI embedding failed: OpenAI API error: 401 - ...

// after
const svc = new OpenAIEmbeddingService({ apiKey: process.env.OPENAI_API_KEY! });
await svc.embed('hello');
Defensive patterns

Strategy: try-catch

Validate before calling

function hasEmbeddingConfig(cfg: { apiKey?: string; model?: string; baseURL?: string }): boolean {
  return typeof cfg.apiKey === 'string' && cfg.apiKey.length > 20
    && (cfg.model ?? 'text-embedding-3-small').length > 0;
}
if (!hasEmbeddingConfig(config)) throw new Error('embedding config incomplete');
const svc = new OpenAIEmbeddingService(config);

Try / catch

try {
  const { embedding } = await svc.embed(text);
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  if (msg.startsWith('OpenAI embedding failed:')) {
    const cause = msg.slice('OpenAI embedding failed:'.length).trim();
    if (cause.includes('401')) throw new Error('bad API key');
    if (cause.includes('429')) await sleep(backoffMs), retry();
    if (cause.includes('timeout') || cause.includes('ETIMEDOUT')) chunk smaller;
  } else throw e;
}

Prevention

When it happens

Trigger: embed(text) with a missing/invalid config.apiKey (the constructor reads config.apiKey directly — 401 from the API), a typo'd config.model (default 'text-embedding-3-small'), input exceeding the model token limit, a timeout beyond config.timeout (30000ms default), or a config.baseURL pointing at a wrong path; callOpenAI retries maxRetries (default 3) times, then embed() wraps the final error.

Common situations: Empty or placeholder apiKey in config; Azure/OpenRouter proxies needing a different baseURL; whole documents fed as one embed() call; retired or misspelled model names.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/4c9a47724659e7fe. Report an issue: GitHub.