{"record":{"id":"7af48005559c46eb","repo":"affaan-m/ECC","slug":"label-must-not-contain-duplicate-values","errorCode":null,"errorMessage":"${label} must not contain duplicate values.","messagePattern":"(.+?) must not contain duplicate values\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":125,"sourceCode":"function validateMemoryId(value) {\n  const normalized = asNonEmptyString(value, 'memory id', 132);\n  if (!MEMORY_ID_PATTERN.test(normalized)) {\n    throw new Error('memory id must match mem_<lowercase-id> and cannot contain a path.');\n  }\n  return normalized;\n}\n\nfunction uniqueStrings(values, { label, limit, validator }) {\n  if (!Array.isArray(values)) {\n    throw new Error(`${label} must be an array.`);\n  }\n  if (values.length > limit) {\n    throw new Error(`${label} has too many values (maximum ${limit}).`);\n  }\n  return values.reduce((result, value) => {\n    const normalized = validator(value);\n    if (result.includes(normalized)) {\n      throw new Error(`${label} must not contain duplicate values.`);\n    }\n    return [...result, normalized];\n  }, []);\n}\n\nfunction validateTimestamp(value, label) {\n  const normalized = asNonEmptyString(value, label, 64);\n  const parsed = new Date(normalized);\n  if (\n    !ISO_TIMESTAMP_PATTERN.test(normalized)\n    || Number.isNaN(parsed.getTime())\n    || parsed.toISOString() !== normalized\n  ) {\n    throw new Error(`${label} must be an ISO-8601 timestamp.`);\n  }\n  return normalized;\n}\n","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/memory-vault-format.js#L107-L143","documentation":"Thrown by uniqueStrings() when two entries in the input array normalize to the same value (the validator is applied before the duplicate check). It enforces a set semantic for list fields so storage and lookup are deterministic.","triggerScenarios":"Passing ['tag-a', 'tag-a'], ['TAG-A', 'tag-a'] when the validator lowercases, or two slugs that trim to the same value.","commonSituations":"Merging tag lists from multiple sources without dedup; case-sensitive copy-paste that produces near-duplicates after normalization.","solutions":["Dedupe the array (e.g. [...new Set(values)]) before passing it in.","Remember the validator may normalize (lowercase, trim) before the duplicate check runs.","Audit the upstream producer if duplicates keep appearing."],"exampleFix":"// before\nuniqueStrings(['api', 'api', 'auth'], { label: 'tags', limit: 32, validator: v => v.toLowerCase() });\n// after\nuniqueStrings([...new Set(['api', 'api', 'auth'])], { label: 'tags', limit: 32, validator: v => v.toLowerCase() });","handlingStrategy":"validation","validationCode":"function dedupe(values) {\n  return [...new Set(values)];\n}\n// pass deduped array to uniqueStrings to avoid the duplicate guard firing:\nresult = uniqueStrings(dedupe(values), opts);","typeGuard":"function hasNoDuplicates(values) {\n  return Array.isArray(values) && new Set(values).size === values.length;\n}","tryCatchPattern":"try {\n  result = uniqueStrings(values, opts);\n} catch (e) {\n  if (/must not contain duplicate values/.test(e.message)) {\n    result = uniqueStrings([...new Set(values)], opts);\n  } else throw e;\n}","preventionTips":["Always dedupe list inputs before submission.","Remember normalization (lowercase/trim) can create duplicates from visually distinct inputs.","When merging documents, run a dedupe pass on tag/link lists."],"tags":["memory-vault","validation","array","duplicate"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}