affaan-m/ECC · error · Error

${label} must be one of: ${allowed.join(', ')}.

Error message

${label} must be one of: ${allowed.join(', ')}.

What it means

Thrown by validateEnum() when the value (after trimming and length-check) is not in the allowed list. Used for memory fields with a closed value set: kind (context/decision/fact/...), scope (project/team/user), trust (unreviewed), status (active/rejected/superseded), and similar.

Source

Thrown at scripts/lib/memory-vault-format.js:94

function asNonEmptyString(value, label, maxChars = 10_000) {
  if (typeof value !== 'string' || value.trim().length === 0) {
    throw new Error(`${label} must be a non-empty string.`);
  }
  const normalized = value.trim();
  if (normalized.length > maxChars) {
    throw new Error(`${label} is too long (maximum ${maxChars} characters).`);
  }
  if (hasUnsafeControlCharacters(normalized)) {
    throw new Error(`${label} must not contain control or bidirectional formatting characters.`);
  }
  return normalized;
}

function validateEnum(value, allowed, label) {
  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;

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Read the allowed values listed in the error message and pick one exactly.
  2. If you believe the value should be valid, upgrade the memory-vault module to a version that includes it.
  3. Avoid inventing values; if none fit, use the closest 'note' kind and add detail in the body.

Example fix

# before
kind: bug
# after
kind: note
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_KINDS = ['context','decision','fact','handoff','lesson','note','preference','runbook'];
function isValidEnum(value, allowed) {
  return typeof value === 'string' && allowed.includes(value.trim());
}
if (!isValidEnum(kind, ALLOWED_KINDS)) {
  throw new Error(`kind must be one of: ${ALLOWED_KINDS.join(', ')}`);
}

Type guard

function isMemoryKind(value) {
  return ['context','decision','fact','handoff','lesson','note','preference','runbook'].includes(value);
}

Try / catch

try {
  result = validateEnum(value, allowed, label);
} catch (e) {
  if (/must be one of:/.test(e.message)) result = validateEnum('note', allowed, label);
  else throw e;
}

Prevention

When it happens

Trigger: Setting kind to 'bug', scope to 'org', status to 'closed', or any value outside the frozen enum arrays.

Common situations: Guessing an enum value instead of checking the schema; copy-pasting from a different memory system; version skew if a new enum value was added upstream but the validator is older.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/4d0c946842b3285f. Report an issue: GitHub.