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
- Supply a non-empty literal name and an actual Array of Float32Array embeddings
- Convert JSON-loaded vectors: embeddings.map(v => Float32Array.from(v)) before the call
- Validate intent records at load time: name is a non-empty string, embeddings is a non-empty array of arrays, then coerce
- 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
- Coerce JSON-loaded vectors with Float32Array.from() — JSON has no typed arrays
- Validate intent records at load time (non-empty name, array of correct-length vectors)
- Dimension mismatches throw on the NEXT line — validate length === router dimension in the same pass
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
- Embedding must be Float32Array of length
- SemanticRouter requires a dimension in config
- each record requires a non-empty numeric vector
- embedBatch() expects an array of strings
- embedding failed
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)