{"record":{"id":"86f29575d198befd","repo":"mem0ai/mem0","slug":"invalid-threshold-threshold-must-be-between-0","errorCode":null,"errorMessage":"Invalid threshold: ${threshold}. Must be between 0 and 1 (inclusive).","messagePattern":"Invalid threshold: (.+?)\\. Must be between 0 and 1 \\(inclusive\\)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/memory/index.ts","lineNumber":190,"sourceCode":"  if (/\\s/.test(trimmed)) {\n    throw new Error(\n      `Invalid ${name}: cannot contain whitespace. Provide a valid identifier without spaces.`,\n    );\n  }\n  return trimmed;\n}\n\n/**\n * Validates search parameters.\n * @throws Error if threshold or topK are invalid\n */\nfunction validateSearchParams(threshold?: number, topK?: number): void {\n  if (threshold !== undefined) {\n    if (typeof threshold !== \"number\" || isNaN(threshold)) {\n      throw new Error(\"threshold must be a valid number\");\n    }\n    if (threshold < 0 || threshold > 1) {\n      throw new Error(\n        `Invalid threshold: ${threshold}. Must be between 0 and 1 (inclusive).`,\n      );\n    }\n  }\n  if (topK !== undefined) {\n    if (typeof topK !== \"number\" || isNaN(topK) || !Number.isInteger(topK)) {\n      throw new Error(\"topK must be a valid integer\");\n    }\n    if (topK < 0) {\n      throw new Error(`Invalid topK: ${topK}. Must be a non-negative integer.`);\n    }\n  }\n}\n\nexport class Memory {\n  private config: MemoryConfig;\n  private customInstructions: string | undefined;\n  private embedder: Embedder;","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/memory/index.ts#L172-L208","documentation":"Thrown by validateSearchParams when threshold is a valid number but lies outside the inclusive [0, 1] range. Threshold is a similarity score cutoff, so values like 1.5 or -0.2 are meaningless and rejected before the vector search executes. The message echoes the offending value.","triggerScenarios":"Calling memory.search with threshold: 5, threshold: 1.2, or a negative value; or treating threshold as a percentage (passing 70 for 70%) instead of a 0–1 fraction.","commonSituations":"Config authored as a percent (70) by someone assuming 0–100 scale; UI sliders exposing 0–100; arithmetic bugs like threshold: score * 100; copy-paste from code expecting a distance bound instead of similarity.","solutions":["Pass a fraction in [0,1]: threshold: 0.7 for 70% similarity.","If your config stores percentages, divide by 100 at the call site: threshold: pct / 100.","Clamp at the boundary when threshold is user-supplied: Math.min(1, Math.max(0, value)).","Recheck semantics: higher threshold = stricter matching; 0 returns everything the store yields."],"exampleFix":"// before\nawait memory.search('preferences', { threshold: 75 }); // treated as percent -> throws\n\n// after\nawait memory.search('preferences', { threshold: 0.75 }); // 0–1 similarity cutoff","handlingStrategy":"validation","validationCode":"function normalizeThreshold(raw: unknown): number | undefined {\n  if (raw === undefined) return undefined;\n  const n = Number(raw);\n  if (!Number.isFinite(n)) return undefined;\n  return Math.min(1, Math.max(0, n)); // clamp percentages/mistakes into range\n}","typeGuard":"function isInRangeThreshold(t: unknown): t is number {\n  return typeof t === 'number' && t >= 0 && t <= 1;\n}","tryCatchPattern":null,"preventionTips":["Store thresholds as 0–1 fractions everywhere in config, never percentages.","Divide percentage inputs by 100 at the boundary and document the unit.","Add tests for 0, 1, and out-of-range boundaries on any user-facing threshold."],"tags":["validation","search","threshold","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}