affaan-m/ECC · error

Invalid mode "${mode}". Allowed modes: ${allowedModes.join('

Error message

Invalid mode "${mode}". Allowed modes: ${allowedModes.join(', ')}

What it means

Thrown by buildAgentCatalog at scripts/lib/agent-compress.js:173-175 when options.mode is not in the allowedModes list (['catalog', 'summary', 'full']). buildAgentCatalog compresses ECC agent markdown files into a token-budgeted catalog; the mode selects how aggressively each agent is compressed (catalog = metadata only, summary = metadata + first paragraph, full = no compression). The mode defaults to 'catalog' when omitted (ito.js:171 — agent-compress.js:171), so this only fires when an explicit invalid value is supplied.

Source

Thrown at scripts/lib/agent-compress.js:174

}

const allowedModes = ['catalog', 'summary', 'full'];

/**
 * Build a compressed catalog from a directory of agents.
 *
 * Modes:
 *  - 'catalog': name, description, tools, model only (~2-3k tokens for 27 agents)
 *  - 'summary': catalog + first paragraph summary (~4-5k tokens)
 *  - 'full':    no compression, full body included
 *
 * Returns { agents: [], stats: { totalAgents, originalBytes, compressedBytes, compressedTokenEstimate, mode } }
 */
function buildAgentCatalog(agentsDir, options = {}) {
  const mode = options.mode || 'catalog';

  if (!allowedModes.includes(mode)) {
    throw new Error(`Invalid mode "${mode}". Allowed modes: ${allowedModes.join(', ')}`);
  }

  const filter = options.filter || null;

  let agents = loadAgents(agentsDir);

  if (typeof filter === 'function') {
    agents = agents.filter(filter);
  }

  const originalBytes = agents.reduce((sum, a) => sum + a.byteSize, 0);

  let compressed;
  if (mode === 'catalog') {
    compressed = agents.map(compressToCatalog);
  } else if (mode === 'summary') {
    compressed = agents.map(compressToSummary);
  } else {

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Use one of: 'catalog', 'summary', 'full' (case-sensitive lowercase).
  2. Omit mode entirely if you want the default ('catalog').
  3. If you need a different compression shape, add it to allowedModes at agent-compress.js:158 and wire a branch into the if/else at lines 188-200.

Example fix

// before
buildAgentCatalog(dir, { mode: 'compact' });
// after
buildAgentCatalog(dir, { mode: 'catalog' });
Defensive patterns

Strategy: type-guard

Validate before calling

const ALLOWED = new Set(['catalog', 'summary', 'full']);
function buildAgentCatalogSafe(dir, options = {}) {
  const mode = options.mode || 'catalog';
  if (!ALLOWED.has(mode)) throw new Error(`Invalid mode '${mode}'`);
  return buildAgentCatalog(dir, { ...options, mode });
}

Type guard

function isAgentCatalogMode(value) {
  return typeof value === 'string'
    && ['catalog', 'summary', 'full'].includes(value);
}

Prevention

When it happens

Trigger: Calling buildAgentCatalog(agentsDir, { mode: 'compact' }), { mode: 'short' }, { mode: 'metadata' }, or any string other than catalog/summary/full. Also fires on typos like 'catlog' or 'Summry'.

Common situations: A caller invented a mode name not in the docs; a refactor renamed a mode but callers were not updated; a config file supplies the mode and a typo slipped in; programmatic callers passing options.compressAs under the wrong key.

Related errors


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