ruvnet/ruflo · error · Error
vector must be a non-empty numeric array
Error message
vector must be a non-empty numeric array
What it means
Thrown by the agenticow_query handler (agenticow-tools.ts:172) when the vector argument is not a non-empty array. HNSW nearest-neighbor search needs a query vector with the same dimension as the store, so an empty, missing, or non-array vector is rejected before the memory file is even opened.
Solutions
- Compute the query embedding first and pass a flat number[] with the store's dimension
- Parse/guard the vector right before the call: Array.isArray(v) && v.length === dim
- Fail loudly if the embedding service returned nothing instead of forwarding undefined
Example fix
// before
await callTool('agenticow_query', { path: p, vector: undefined, k: 10 });
// throws: vector must be a non-empty numeric array
// after
const q = await embed(userQuery);
if (!Array.isArray(q) || q.length !== 384) throw new Error('embedding failed');
await callTool('agenticow_query', { path: p, vector: q, k: 10 }); Defensive patterns
Strategy: validation
Validate before calling
function isNumericVector(v: unknown): v is number[] {
return Array.isArray(v) && v.length > 0 && v.every((n) => typeof n === 'number' && Number.isFinite(n));
}
if (!isNumericVector(queryVector)) throw new TypeError('embedding step failed — no query vector'); Type guard
function isNumericVector(v: unknown): v is number[] {
return Array.isArray(v) && v.length > 0 && v.every((n) => typeof n === 'number' && Number.isFinite(n));
} Prevention
- Fail loudly when the embedding service returns undefined/null instead of forwarding it
- Check vector length matches the store dimension before querying
When it happens
Trigger: Calling agenticow_query with vector omitted, vector: [], vector as a string ('[0.1, 0.2]'), or a nested wrapper ({values: [...]}). The check is Array.isArray(vector) && vector.length > 0.
Common situations: Reusing an embedding variable that came back undefined from a failed API call; double-stringified JSON vectors; query built from a search box without an embedding step; dimension mismatch with the file (passes this check, fails later).
Related errors
- each record requires a non-empty numeric vector
- at least one candidate is required
- candidate must ingest at least one vector
- label exceeds 256 chars
- label is required
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/5b4177942feb84b1.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/mcp-tools/agenticow-tools.ts:172
tags: ['agenticow', 'memory', 'cow', 'query', 'read', 'search'],
inputSchema: {
type: 'object',
properties: {
path: { type: 'string', description: 'Path to .rvf memory file' },
vector: { type: 'array', items: { type: 'number' }, description: 'Query embedding vector' },
k: { type: 'integer', description: 'Number of nearest neighbors to return', default: 10 },
efSearch: { type: 'integer', description: 'HNSW efSearch per lineage store (higher = better recall, slower)' },
},
required: ['path', 'vector'],
},
handler: async (input) => {
const api = await loadAgenticow();
if (!api) return degradedResult('agenticow-not-found');
const path = resolveMemoryPath(String(input.path));
const vector = input.vector as number[];
if (!Array.isArray(vector) || vector.length === 0) {
throw new Error('vector must be a non-empty numeric array');
}
const k = typeof input.k === 'number' ? input.k : 10;
const opts: Record<string, unknown> = {};
if (typeof input.efSearch === 'number') opts.efSearch = input.efSearch;
const mem = await openWithLineage(api, path);
try {
const hits = await mem.query(vector, k, opts);
return { success: true, path, k, hits };
} finally {
await mem.close?.();
}
},
},
{
name: 'agenticow_diff',
description: 'agenticow — show what a branch changed relative to its lineage: {added, overridden, deleted} vector-id lists. Use when you are about to promote and want to preview the exact merge, or when auditing what a branch actually wrote. Diffing by re-querying is wrong because deletions (tombstones) are invisible to a read — diff() surfaces them explicitly. Requires the branch was opened with edit tracking (default on).',
category: 'memory',
tags: ['agenticow', 'memory', 'cow', 'diff'],View on GitHub (pinned to fa13ee4ad6)