ruvnet/ruflo · error

Must provide name and embeddings array

Error message

Must provide name and embeddings array

What it means

addIntentWithEmbeddings() validates its inputs before storing: name must be a non-empty string and embeddings must be an Array. This is the first and loosest check — the next loop additionally requires every element to be a Float32Array of exactly config.dimension. This error fires when either the name or the array shape is wrong at the top level.

Solutions

  1. Supply a non-empty literal name and an actual Array of Float32Array embeddings
  2. Convert JSON-loaded vectors: embeddings.map(v => Float32Array.from(v)) before the call
  3. Validate intent records at load time: name is a non-empty string, embeddings is a non-empty array of arrays, then coerce
  4. Double-check that every embedding's length equals the dimension you constructed the router with

Example fix

// before
router.addIntentWithEmbeddings(intent.label, intent.vectors); // label undefined → throws
// after
const name = intent.name;
const embeddings = (intent.vectors ?? []).map((v: number[]) => Float32Array.from(v));
if (!name || !Array.isArray(embeddings) || embeddings.length === 0) {
  throw new Error(`invalid intent record: ${JSON.stringify(intent).slice(0, 80)}`);
}
router.addIntentWithEmbeddings(name, embeddings);
Defensive patterns

Strategy: validation

Validate before calling

function toIntent(record: { name?: unknown; vectors?: unknown }) {
  const name = typeof record.name === 'string' ? record.name.trim() : '';
  const embeddings = Array.isArray(record.vectors)
    ? record.vectors.map((v: number[]) => Float32Array.from(v))
    : [];
  if (!name || embeddings.length === 0) return null; // filter bad records before the call
  return { name, embeddings };
}

Type guard

type IntentInput = { name: string; embeddings: Float32Array[] };
function isIntentInput(x: unknown): x is IntentInput {
  return !!x && typeof (x as any).name === 'string' && (x as any).name.length > 0
    && Array.isArray((x as any).embeddings);
}

Try / catch

try {
  router.addIntentWithEmbeddings(name, embeddings);
} catch (e) {
  if (e instanceof Error && (e.message.startsWith('Must provide name and embeddings') || e.message.startsWith('Embedding must be Float32Array'))) {
    console.warn(`skipping malformed intent ${JSON.stringify(name)}`); // bad record, not fatal
  } else throw e;
}

Prevention

When it happens

Trigger: Calling with a name that is undefined/'' (often a destructured or interpolated variable that was never set); passing embeddings as a plain number[][] instead of Float32Array[] (caught here only if not an Array at all — plain arrays pass this check and fail the next one); passing null embeddings.

Common situations: Building intents from data files where a key is misspelled (name vs label); coercing JSON-loaded embeddings that arrive as nested arrays; optional-chained lookups (intent?.name) yielding undefined for a malformed record.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at v3/@claude-flow/cli/src/ruvector/semantic-router.ts:56

  constructor(config: RouterConfig) {
    if (!config || typeof config.dimension !== 'number') {
      throw new Error('SemanticRouter requires a dimension in config');
    }
    this.dimension = config.dimension;
    this.metric = config.metric ?? 'cosine';
  }

  /**
   * Add an intent with pre-computed embeddings
   */
  addIntentWithEmbeddings(
    name: string,
    embeddings: Float32Array[],
    metadata: Record<string, unknown> = {}
  ): void {
    if (!name || !Array.isArray(embeddings)) {
      throw new Error('Must provide name and embeddings array');
    }

    // Validate embeddings
    for (const emb of embeddings) {
      if (!(emb instanceof Float32Array) || emb.length !== this.dimension) {
        throw new Error(`Embedding must be Float32Array of length ${this.dimension}`);
      }
    }

    // Normalize embeddings for cosine similarity
    const normalizedEmbeddings = embeddings.map(emb => this.normalize(emb));

    this.intents.set(name, {
      name,
      embeddings: normalizedEmbeddings,
      metadata,
    });
    this.totalVectors += embeddings.length;

View on GitHub (pinned to fa13ee4ad6)