{"record":{"id":"69b6d03db9508470","repo":"ruvnet/ruflo","slug":"each-record-requires-a-non-empty-numeric-vector","errorCode":null,"errorMessage":"each record requires a non-empty numeric vector","messagePattern":"each record requires a non-empty numeric vector","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/mcp-tools/agenticow-tools.ts","lineNumber":132,"sourceCode":"            required: ['vector'],\n          },\n        },\n        dimension: { type: 'integer', description: 'Vector dimension (required only when path does not exist yet)' },\n      },\n      required: ['path', 'records'],\n    },\n    handler: async (input) => {\n      const api = await loadAgenticow();\n      if (!api) return degradedResult('agenticow-not-found');\n\n      const path = resolveMemoryPath(String(input.path));\n      const records = input.records as Array<{ id?: number; vector: number[]; text?: string }>;\n      if (!Array.isArray(records) || records.length === 0) {\n        throw new Error('records must be a non-empty array of {id?, vector, text?}');\n      }\n      for (const r of records) {\n        if (!Array.isArray(r.vector) || r.vector.length === 0) {\n          throw new Error('each record requires a non-empty numeric vector');\n        }\n      }\n      const dim = (input.dimension as number | undefined) ?? records[0].vector.length;\n      const mem = await openWithLineage(api, path, dim);\n      try {\n        const result = await mem.ingest(records.map((r) => ({\n          ...(typeof r.id === 'number' ? { id: r.id } : {}),\n          vector: r.vector,\n          ...(r.text !== undefined ? { text: r.text } : {}),\n        })));\n        await mem.save?.(manifestFor(path));\n        return { success: true, path, ingested: result };\n      } finally {\n        await mem.close?.();\n      }\n    },\n  },\n  {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/mcp-tools/agenticow-tools.ts#L114-L150","documentation":"Thrown by the agenticow_ingest handler (agenticow-tools.ts:132) when any record's vector field is not a non-empty array. agenticow stores pre-computed numeric vectors (HNSW-indexed) — text is optional metadata, not something that gets embedded on the fly — so every record must carry its own non-empty vector.","triggerScenarios":"A record with vector omitted (e.g. {text: 'doc'} expecting auto-embedding), vector: [], vector passed as a string ('[0.1,0.2]') or comma-separated '0.1,0.2', or vector: null. One bad record in the batch fails the entire call.","commonSituations":"Assuming the tool embeds text like a RAG pipeline; vectors JSON.stringify'd twice so they arrive as strings; sparse sources where some rows lack embeddings; undefined after destructuring a renamed field (e.g. record.embedding vs record.vector).","solutions":["Pre-compute embeddings and pass a real number[] per record (e.g. via the claude-flow embeddings tools) — dimension must match the file's dimension","Parse stringified vectors before sending: JSON.parse(rec.vector)","Filter or reject records lacking vectors before the call, and align the field name to 'vector'"],"exampleFix":"// before\nawait callTool('agenticow_ingest', {\n  path: p, dimension: 384,\n  records: [{ text: 'a doc with no embedding' }], // throws\n});\n\n// after\nconst vectors = await embed(texts); // pre-compute\nawait callTool('agenticow_ingest', {\n  path: p, dimension: 384,\n  records: texts.map((t, i) => ({ vector: vectors[i], text: t })),\n});","handlingStrategy":"validation","validationCode":"function isNumericVector(v: unknown): v is number[] {\n  return Array.isArray(v) && v.length > 0 && v.every((n) => typeof n === 'number' && Number.isFinite(n));\n}\nconst bad = records.filter((r) => !isNumericVector(r.vector));\nif (bad.length) throw new TypeError(`${bad.length} records lack a numeric vector`);","typeGuard":"function isNumericVector(v: unknown): v is number[] {\n  return Array.isArray(v) && v.length > 0 && v.every((n) => typeof n === 'number' && Number.isFinite(n));\n}","tryCatchPattern":null,"preventionTips":["This API stores raw vectors — always run your embedding step before ingest, never send text-only records","Assert every vector's length equals the file's dimension before submitting the batch","Beware double-stringified JSON turning vectors into strings"],"tags":["validation","agenticow","vectors","embeddings","mcp"],"backgroundTag":"invalid-vector-format","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}