supermemoryai/supermemory · error · Error

Vectors must contain only numbers

Error message

Vectors must contain only numbers

What it means

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.

Source

Thrown at packages/lib/similarity.ts:27

	vectorA: number[],
	vectorB: number[],
): number => {
	if (vectorA.length !== vectorB.length) {
		throw new Error("Vectors must have the same length")
	}

	let dotProduct = 0

	for (let i = 0; i < vectorA.length; i++) {
		const vectorAi = vectorA[i]
		const vectorBi = vectorB[i]
		if (
			typeof vectorAi !== "number" ||
			typeof vectorBi !== "number" ||
			isNaN(vectorAi) ||
			isNaN(vectorBi)
		) {
			throw new Error("Vectors must contain only numbers")
		}
		dotProduct += vectorAi * vectorBi
	}

	return dotProduct
}

/**
 * Calculate semantic similarity between two documents
 * Returns a value between 0 and 1, where 1 is most similar
 */
export const calculateSemanticSimilarity = (
	document1Embedding: number[] | null,
	document2Embedding: number[] | null,
): number => {
	// If we have both embeddings, use cosine similarity
	if (
		document1Embedding &&

View on GitHub (pinned to d436792e77)

Solutions

  1. Sanitize/validate vectors at ingestion: filter or reject non-finite entries
  2. Fix the upstream code producing NaN embeddings (division by zero, bad normalization)
  3. Add a type guard before comparison loops

Example fix

// before
const score = cosineSimilarity(a, b)

// after
const isNumericVector = (v: unknown[]): v is number[] =>
  v.every((x) => typeof x === 'number' && Number.isFinite(x))
if (isNumericVector(a) && isNumericVector(b) && a.length === b.length) {
  const score = cosineSimilarity(a, b)
}
Defensive patterns

Strategy: type-guard

Validate before calling

const valid = [a, b].every((v) => Array.isArray(v) && v.every((x) => typeof x === 'number' && Number.isFinite(x)))

Type guard

const isNumericVector = (v: unknown): v is number[] => Array.isArray(v) && v.every((x) => typeof x === 'number' && Number.isFinite(x))

Try / catch

try { cosineSimilarity(a, b) } catch (e) { if (e instanceof Error && e.message.includes('only numbers')) { /* quarantine bad vector */ } throw-or-skip }

Prevention

When it happens

Trigger: 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.

Common situations: Deserializing embeddings from a database column that null-padded missing dimensions; bugs in embedding generation; JSON.parse of malformed vectors yielding mixed types.

Related errors


AI-assisted analysis of supermemoryai/supermemory@d436792e77 (2026-08-28). Data as JSON: /api/errors/7e67193f1b1a2a97. Report an issue: GitHub.