affaan-m/ECC · error · Error
memory id must match mem_<lowercase-id> and cannot contain a
Error message
memory id must match mem_<lowercase-id> and cannot contain a path.
What it means
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.
Source
Thrown at scripts/lib/memory-vault-format.js:110
const normalized = asNonEmptyString(value, label, 64);
if (!allowed.includes(normalized)) {
throw new Error(`${label} must be one of: ${allowed.join(', ')}.`);
}
return normalized;
}
function validateSlug(value, label) {
const normalized = asNonEmptyString(value, label, 64);
if (!SLUG_PATTERN.test(normalized)) {
throw new Error(`${label} must be a lowercase letters/numbers slug.`);
}
return normalized;
}
function validateMemoryId(value) {
const normalized = asNonEmptyString(value, 'memory id', 132);
if (!MEMORY_ID_PATTERN.test(normalized)) {
throw new Error('memory id must match mem_<lowercase-id> and cannot contain a path.');
}
return normalized;
}
function uniqueStrings(values, { label, limit, validator }) {
if (!Array.isArray(values)) {
throw new Error(`${label} must be an array.`);
}
if (values.length > limit) {
throw new Error(`${label} has too many values (maximum ${limit}).`);
}
return values.reduce((result, value) => {
const normalized = validator(value);
if (result.includes(normalized)) {
throw new Error(`${label} must not contain duplicate values.`);
}
return [...result, normalized];
}, []);View on GitHub (pinned to 01e15490f0)
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.
Example fix
// before
validateMemoryId('memory-auth-decision');
// after
validateMemoryId('mem_auth_decision_v2'); Defensive patterns
Strategy: validation
Validate before calling
const ID_RE = /^mem_[a-z0-9][a-z0-9_-]{2,127}$/;
function toMemoryId(seed) {
const cleaned = String(seed).toLowerCase().replace(/[^a-z0-9_-]/g, '').slice(0, 128);
return `mem_${cleaned}`;
}
function isValidMemoryId(value) { return ID_RE.test(value); } Type guard
function isMemoryId(value) {
return typeof value === 'string' && /^mem_[a-z0-9][a-z0-9_-]{2,127}$/.test(value);
} Try / catch
try {
result = validateMemoryId(value);
} catch (e) {
if (/memory id must match/.test(e.message)) result = validateMemoryId(toMemoryId(value));
else throw e;
} Prevention
- 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.
When it happens
Trigger: Passing 'memory-1', 'mem_ABC', 'mem_a/b', 'mem_' (too short after prefix), or an id over 132 characters total.
Common situations: Generating IDs from uppercased or path-joined sources; using a UUID with dashes that are not lowercased; trimming the mem_ prefix by accident.
Related errors
- ${label} must be a non-empty string.
- ${label} must be a lowercase letters/numbers slug.
- ${label} must be an array.
- Invalid format: ${parsed.format}. Use text, json, or markdow
- ${label} is too long (maximum ${maxChars} characters).
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/abdee46c569e1828.
Report an issue: GitHub.