{"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":"exception","errorClass":null,"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/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/memory-vault-format.js#L92-L128","documentation":"validateMemoryId checks that a memory id is a string of at most 132 characters matching /^mem_[a-z0-9][a-z0-9_-]{2,127}$/ — it must start with the literal 'mem_' followed by at least 3 lowercase characters. The error message also signals path-traversal protection: ids containing '/', '..', or backslashes are rejected so an id can never escape the vault directory.","triggerScenarios":"Calling normalizeMemory or the memoryId helper with an id like 'abc123' (missing mem_ prefix), 'MEM_abc' (uppercase), 'mem_a' (too short, needs 3+ chars after prefix), 'mem_../../secret', or a non-string value.","commonSituations":"Generating ids with crypto.randomUUID() (contains hyphens are OK but lacks mem_ prefix); using uppercase UUIDs; constructing ids by concatenating user paths; legacy records stored with the old id format before the mem_ convention was adopted.","solutions":["Prefix the id with 'mem_' and lowercase all characters, e.g. mem_ + crypto.randomUUID().toLowerCase().","Verify at least 3 characters follow the prefix and only [a-z0-9_-] are used (no dots, slashes, or spaces).","Strip any path segments ('/', '..') from the value before formatting.","Keep the total length at or below 132 characters."],"exampleFix":"// before\nconst id = crypto.randomUUID(); // '3f8a...' -> rejected\n// after\nconst id = 'mem_' + crypto.randomUUID().toLowerCase().replace(/-/g, '');","handlingStrategy":"validation","validationCode":"function isValidMemoryId(v) { return typeof v === 'string' && /^mem_[a-z0-9][a-z0-9_-]{2,127}$/.test(v) && v.length <= 132; }\nif (!isValidMemoryId(id)) id = 'mem_' + String(id).toLowerCase().replace(/[^a-z0-9_-]/g, '').slice(0, 127);","typeGuard":"const isMemoryId = (v) => typeof v === 'string' && /^mem_[a-z0-9][a-z0-9_-]{2,127}$/.test(v);","tryCatchPattern":"try { normalizeMemory(mem); } catch (e) { if (e.message.includes('must match mem_')) { mem.id = toMemoryId(mem.id); } else throw e; }","preventionTips":["Always mint ids via a single helper: 'mem_' + crypto.randomUUID().toLowerCase().replace(/-/g, '')","Never concatenate user/path input into an id","Reject ids without the mem_ prefix at ingestion boundaries","Keep ids lowercase end-to-end (UUIDs from crypto are uppercase-prone in some environments)"],"tags":["validation","identifier","memory-vault","path-traversal"],"backgroundTag":"invalid-identifier-format","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}