affaan-m/ECC · error

must be one of: .

Error message

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

What it means

validateEnum constrains a field to a fixed set of allowed values (via asNonEmptyString first, cap 64 chars). If the normalized value is not found in the allowed array, the error lists the accepted values, e.g. 'trust must be one of: public, untrusted.'

Solutions

  1. Use exactly one of the values listed in the error message, matching case.
  2. Import/export canonical values from the library's constants rather than hardcoding strings.
  3. Normalize the value (lowercase/trim) before validating.
  4. Migrate old records whose enum vocabulary predates the current version.

Example fix

// before
validateEnum('Public', ['public', 'untrusted'], 'trust')
// after
validateEnum('public', ['public', 'untrusted'], 'trust')
Defensive patterns

Strategy: validation

Validate before calling

const TRUST_LEVELS = ['public', 'untrusted']
if (!TRUST_LEVELS.includes(String(raw.trust ?? '').toLowerCase())) {
  throw new Error(`trust must be one of: ${TRUST_LEVELS.join(', ')}`)
}

Type guard

function isAllowedEnum(v, allowed) {
  return typeof v === 'string' && allowed.includes(v.trim())
}
if (!isAllowedEnum(input.trust, ['public', 'untrusted'])) throw new TypeError('trust has an invalid value')

Try / catch

try {
  const memory = normalizeMemory(raw)
} catch (err) {
  if (err.message.includes('must be one of')) {
    console.error(err.message) // message lists the allowed values
  } else throw err
}

Prevention

When it happens

Trigger: Calling validateEnum(value, allowed, label) (directly or via normalizeMemory for scopes/kinds/trust) with a value outside the allowed list — typos, different casing, or a value from an older schema version.

Common situations: Writing 'Trust: public' or 'PUBLIC' instead of lowercase 'public'; a kind renamed in a newer vault version; hardcoding a scope string that drifted from the canonical list; importing records from another tool with different vocab.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/4d0c946842b3285f. Report an issue: GitHub.

Appendix: 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 8321021c54)