ruvnet/ruflo · error · Error

HNSW pattern limit reached (${HNSW_MAX_SAFE_PATTERNS}).

Error message

HNSW pattern limit reached (${HNSW_MAX_SAFE_PATTERNS}).

What it means

The WASM HNSW router caps stored patterns at HNSW_MAX_SAFE_PATTERNS (1024, the safe ceiling validated for @ruvector/ruvllm-wasm v2.0.2 which fixed connect_node ordering). addPattern() on the object returned by createHnswRouter() throws once the in-process counter reaches 1024, regardless of the maxPatterns value passed to the underlying constructor. This is a JS-side guard that fires before the WASM addPattern call, so partial writes do not occur.

Source

Thrown at v3/@claude-flow/cli/src/ruvector/ruvllm-wasm.ts:173

  route: (query: Float32Array, k?: number) => HnswRouteResult[];
  clear: () => void;
  patternCount: () => number;
  toJson: () => string;
}> {
  await initRuvllmWasm();
  const mod = await import('@ruvector/ruvllm-wasm');

  const router = new mod.HnswRouterWasm(config.dimensions, config.maxPatterns);
  if (config.efSearch) {
    router.setEfSearch(config.efSearch);
  }

  let count = 0;

  return {
    addPattern(pattern: HnswPattern): boolean {
      if (count >= HNSW_MAX_SAFE_PATTERNS) {
        throw new Error(
          `HNSW pattern limit reached (${HNSW_MAX_SAFE_PATTERNS}).`
        );
      }
      const metadataJson = JSON.stringify(pattern.metadata ?? {});
      // addPattern requires 3 args: (embedding, name, metadata_json)
      const ok = router.addPattern(pattern.embedding, pattern.name, metadataJson);
      if (ok) count++;
      return ok;
    },
    route(query: Float32Array, k = 3): HnswRouteResult[] {
      const raw = router.route(query, k);
      return Array.from(raw).map((r: any) => ({
        name: r.name ?? r.pattern_name ?? '',
        score: r.score ?? r.distance ?? 0,
        metadata: r.metadata ? (typeof r.metadata === 'string' ? JSON.parse(r.metadata) : r.metadata) : undefined,
      }));
    },
    clear(): void {

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Reduce the pattern set to <=1024 by deduplicating or clustering before addPattern.
  2. Call router.clear() and rebuild with a curated subset when the corpus exceeds 1024.
  3. If you genuinely need more, shard across multiple HnswRouterWasm instances keyed by namespace and fan out route() queries.
  4. Switch to the DiskANN backend (diskann-backend.ts) which targets larger-than-RAM pattern counts, instead of HNSW.

Example fix

// before: blindly streaming all patterns
for (const p of allPatterns) router.addPattern(p); // throws at 1025th

// after: cap and shard
const SHARD_SIZE = 1024;
for (let i = 0; i < allPatterns.length; i += SHARD_SIZE) {
  const shard = shards[i / SHARD_SIZE] ??= await createHnswRouter(config);
  for (const p of allPatterns.slice(i, i + SHARD_SIZE)) shard.addPattern(p);
}
Defensive patterns

Strategy: validation

Validate before calling

// Before calling addPattern, check the live count and the cap.
import { HNSW_MAX_SAFE_PATTERNS } from './ruvllm-wasm';

function safeAdd(router, pattern) {
  if (router.patternCount() >= HNSW_MAX_SAFE_PATTERNS) {
    throw new Error(`Cannot add: cap is ${HNSW_MAX_SAFE_PATTERNS}; shard or clear first.`);
  }
  return router.addPattern(pattern);
}

Type guard

function isHnswPattern(p): p is { embedding: Float32Array; name: string; metadata?: Record<string, unknown> } {
  return p != null && p.embedding instanceof Float32Array && typeof p.name === 'string';
}

Prevention

When it happens

Trigger: Calling addPattern(pattern) on the handle from createHnswRouter() after already successfully adding 1024 patterns (count is only incremented when router.addPattern returns truthy). Typical when bulk-loading a large embedding corpus or treating the HNSW router as a long-term memory store.

Common situations: Migration scripts that replay thousands of historical patterns into a fresh router; setting config.maxPatterns above 1024 expecting the cap to follow it (it does not — the JS guard is fixed at 1024); merging multiple intent catalogs without dedup; running long-lived daemon processes that accumulate patterns without calling clear().

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/305f866b4e5e0293. Report an issue: GitHub.