{"record":{"id":"7e67193f1b1a2a97","repo":"supermemoryai/supermemory","slug":"vectors-must-contain-only-numbers","errorCode":null,"errorMessage":"Vectors must contain only numbers","messagePattern":"Vectors must contain only numbers","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/lib/similarity.ts","lineNumber":27,"sourceCode":"\tvectorA: number[],\n\tvectorB: number[],\n): number => {\n\tif (vectorA.length !== vectorB.length) {\n\t\tthrow new Error(\"Vectors must have the same length\")\n\t}\n\n\tlet dotProduct = 0\n\n\tfor (let i = 0; i < vectorA.length; i++) {\n\t\tconst vectorAi = vectorA[i]\n\t\tconst vectorBi = vectorB[i]\n\t\tif (\n\t\t\ttypeof vectorAi !== \"number\" ||\n\t\t\ttypeof vectorBi !== \"number\" ||\n\t\t\tisNaN(vectorAi) ||\n\t\t\tisNaN(vectorBi)\n\t\t) {\n\t\t\tthrow new Error(\"Vectors must contain only numbers\")\n\t\t}\n\t\tdotProduct += vectorAi * vectorBi\n\t}\n\n\treturn dotProduct\n}\n\n/**\n * Calculate semantic similarity between two documents\n * Returns a value between 0 and 1, where 1 is most similar\n */\nexport const calculateSemanticSimilarity = (\n\tdocument1Embedding: number[] | null,\n\tdocument2Embedding: number[] | null,\n): number => {\n\t// If we have both embeddings, use cosine similarity\n\tif (\n\t\tdocument1Embedding &&","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/supermemoryai/supermemory/blob/d436792e777a99865939dd543c8d1a16d57f54ec/packages/lib/similarity.ts#L9-L45","documentation":"cosineSimilarity throws when any element of either vector is not a finite number (non-number type or NaN). Arithmetic on NaN would silently produce NaN results, so the library fails fast instead.","triggerScenarios":"Passing vectors parsed from JSON that contain null/string values, vectors with NaN entries from a bad embedding computation, or undefined holes in sparse arrays.","commonSituations":"Deserializing embeddings from a database column that null-padded missing dimensions; bugs in embedding generation; JSON.parse of malformed vectors yielding mixed types.","solutions":["Sanitize/validate vectors at ingestion: filter or reject non-finite entries","Fix the upstream code producing NaN embeddings (division by zero, bad normalization)","Add a type guard before comparison loops"],"exampleFix":"// before\nconst score = cosineSimilarity(a, b)\n\n// after\nconst isNumericVector = (v: unknown[]): v is number[] =>\n  v.every((x) => typeof x === 'number' && Number.isFinite(x))\nif (isNumericVector(a) && isNumericVector(b) && a.length === b.length) {\n  const score = cosineSimilarity(a, b)\n}","handlingStrategy":"type-guard","validationCode":"const valid = [a, b].every((v) => Array.isArray(v) && v.every((x) => typeof x === 'number' && Number.isFinite(x)))","typeGuard":"const isNumericVector = (v: unknown): v is number[] => Array.isArray(v) && v.every((x) => typeof x === 'number' && Number.isFinite(x))","tryCatchPattern":"try { cosineSimilarity(a, b) } catch (e) { if (e instanceof Error && e.message.includes('only numbers')) { /* quarantine bad vector */ } throw-or-skip }","preventionTips":["Validate embeddings at ingestion time","Reject null/NaN dimensions at the DB boundary","Add unit tests for malformed vectors"],"tags":["math","embedding","validation","nan"],"backgroundTag":"invalid-vector-data","analyzedSha":"d436792e777a99865939dd543c8d1a16d57f54ec","analyzedAt":"2026-08-28T18:04:46.947Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}