{"record":{"id":"abdee46c569e1828","repo":"affaan-m/ECC","slug":"memory-id-must-match-mem-lowercase-id-and-cannot","errorCode":null,"errorMessage":"memory id must match mem_<lowercase-id> and cannot contain a path.","messagePattern":"memory id must match mem_<lowercase-id> and cannot contain a path\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":110,"sourceCode":"  const normalized = asNonEmptyString(value, label, 64);\n  if (!allowed.includes(normalized)) {\n    throw new Error(`${label} must be one of: ${allowed.join(', ')}.`);\n  }\n  return normalized;\n}\n\nfunction validateSlug(value, label) {\n  const normalized = asNonEmptyString(value, label, 64);\n  if (!SLUG_PATTERN.test(normalized)) {\n    throw new Error(`${label} must be a lowercase letters/numbers slug.`);\n  }\n  return normalized;\n}\n\nfunction 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  }, []);","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/memory-vault-format.js#L92-L128","documentation":"Thrown by validateMemoryId() when the trimmed value does not match MEMORY_ID_PATTERN (/^mem_[a-z0-9][a-z0-9_-]{2,127}$/). IDs must start with the literal prefix mem_, then 3–128 lowercase alphanumeric characters, underscores, or hyphens, and must not contain path separators.","triggerScenarios":"Passing 'memory-1', 'mem_ABC', 'mem_a/b', 'mem_' (too short after prefix), or an id over 132 characters total.","commonSituations":"Generating IDs from uppercased or path-joined sources; using a UUID with dashes that are not lowercased; trimming the mem_ prefix by accident.","solutions":["Prefix the id with mem_ and lowercase the remainder.","Remove any path separators (/ or \\\\) from the id.","Keep the suffix between 3 and 128 characters."],"exampleFix":"// before\nvalidateMemoryId('memory-auth-decision');\n// after\nvalidateMemoryId('mem_auth_decision_v2');","handlingStrategy":"validation","validationCode":"const ID_RE = /^mem_[a-z0-9][a-z0-9_-]{2,127}$/;\nfunction toMemoryId(seed) {\n  const cleaned = String(seed).toLowerCase().replace(/[^a-z0-9_-]/g, '').slice(0, 128);\n  return `mem_${cleaned}`;\n}\nfunction isValidMemoryId(value) { return ID_RE.test(value); }","typeGuard":"function isMemoryId(value) {\n  return typeof value === 'string' && /^mem_[a-z0-9][a-z0-9_-]{2,127}$/.test(value);\n}","tryCatchPattern":"try {\n  result = validateMemoryId(value);\n} catch (e) {\n  if (/memory id must match/.test(e.message)) result = validateMemoryId(toMemoryId(value));\n  else throw e;\n}","preventionTips":["Always prefix generated ids with mem_ and lowercase the suffix.","Derive ids from stable inputs (timestamps + random) rather than user-provided text.","Reject path separators early when ids are built from path-like inputs."],"tags":["memory-vault","validation","id","format"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}