{"record":{"id":"cbab52dacc6909fd","repo":"ruvnet/ruflo","slug":"embedding-service-not-initialized","errorCode":null,"errorMessage":"Embedding service not initialized","messagePattern":"Embedding service not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/hooks/src/reasoningbank/index.ts","lineNumber":954,"sourceCode":"        cacheSize: 1000,\n      });\n    }\n  }\n\n  async embed(text: string): Promise<Float32Array> {\n    const cacheKey = text.slice(0, 200);\n    if (this.cache.has(cacheKey)) {\n      return this.cache.get(cacheKey)!;\n    }\n\n    if (this.service) {\n      const result = await this.service.embed(text);\n      const embedding = result.embedding;\n      this.cache.set(cacheKey, embedding);\n      return embedding;\n    }\n\n    throw new Error('Embedding service not initialized');\n  }\n}\n\n/**\n * Fallback embedding service (hash-based)\n */\nclass FallbackEmbeddingService implements IEmbeddingService {\n  private dimensions: number;\n  private cache: Map<string, Float32Array> = new Map();\n\n  constructor(dimensions: number = 384) {\n    this.dimensions = dimensions;\n  }\n\n  async embed(text: string): Promise<Float32Array> {\n    const cacheKey = text.slice(0, 200);\n    if (this.cache.has(cacheKey)) {\n      return this.cache.get(cacheKey)!;","sourceCodeStart":936,"sourceCodeEnd":972,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/hooks/src/reasoningbank/index.ts#L936-L972","documentation":"The cached embedding wrapper in the hooks ReasoningBank module throws from embed(text) when its internal service handle is null — meaning initialize() was never called (or did not complete) so there is no IEmbeddingService to delegate to. The cache lookup happens first, so previously embedded strings still return; only new text triggers the throw.","triggerScenarios":"Constructing the embedding service wrapper and calling await embedder.embed(text) before await embedder.initialize() resolves — e.g. fire-and-forget initialization, a failed initialize whose error was swallowed, or embed invoked from a request handler racing the startup sequence.","commonSituations":"Missing await on an async initialize in bootstrap; initialize() throwing for the real embedding backend and the caller continuing anyway; embed called during shutdown after the service was torn down; tests skipping initialization for speed.","solutions":["Await the embedding service's initialize() before any embed() call (gate request handling on startup completion)","If the real embedding backend failed to initialize, fall back to the hash-based FallbackEmbeddingService instead of leaving the wrapper uninitialized","Expose and check an isInitialized flag (or track readiness in your own bootstrap) before scheduling embed work"],"exampleFix":"// before\nconst embedder = createEmbeddingService(config);\n// initialize() never awaited (or failed silently)\nawait embedder.embed('hello'); // throws: not initialized\n\n// after\nconst embedder = createEmbeddingService(config);\nawait embedder.initialize(); // must complete first\nawait embedder.embed('hello');","handlingStrategy":"validation","validationCode":"// Gate embed calls on completed initialization\nlet embeddingsReady = false;\nasync function boot() {\n  await embedder.initialize();\n  embeddingsReady = true;\n}\nasync function safeEmbed(text: string): Promise<Float32Array> {\n  if (!embeddingsReady) throw new Error('embeddings not initialized yet');\n  return embedder.embed(text);\n}","typeGuard":"interface InitializableEmbedder {\n  initialize(): Promise<void>;\n  embed(t: string): Promise<Float32Array>;\n}\nfunction isReady(flag: boolean): boolean {\n  return flag; // pair with the readiness flag set after initialize() resolves\n}","tryCatchPattern":"try {\n  vec = await embedder.embed(text);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Embedding service not initialized') {\n    await embedder.initialize(); // one retry after completing init\n    vec = await embedder.embed(text);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always await initialize() in bootstrap before accepting traffic that embeds text","If the real embedding backend fails to init, switch to the hash-based fallback service instead of continuing half-initialized","Add a readiness check to health probes that covers embedding initialization"],"tags":["embeddings","reasoningbank","hooks","initialization","async-race"],"backgroundTag":"service-not-initialized","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}