nanocoai/nanoclaw · error

--${column.name.replace(/_/g, '-')} must be a number

Error message

--${column.name.replace(/_/g, '-')} must be a number

What it means

The walk counts every entry (files AND directories) toward MAX_PLUGIN_FILES; exceeding it throws. Empty-dir breadth bombs trip the same bound as file bombs.

Source

Thrown at src/cli/crud.ts:172

}

export function getResource(plural: string): ResourceDef | undefined {
  return resources.get(plural);
}

// ---------------------------------------------------------------------------
// Generic SQL handlers
// ---------------------------------------------------------------------------

function visibleColumns(def: ResourceDef): string[] {
  return def.columns.map((c) => c.name);
}

function coerceListFilter(column: ColumnDef, value: unknown): unknown {
  switch (column.type) {
    case 'number': {
      const number = Number(value);
      if (Number.isNaN(number)) throw new Error(`--${column.name.replace(/_/g, '-')} must be a number`);
      return number;
    }
    case 'boolean':
      if (value === true || value === 'true' || value === '1' || value === 1) return 1;
      if (value === false || value === 'false' || value === '0' || value === 0) return 0;
      throw new Error(`--${column.name.replace(/_/g, '-')} must be true or false`);
    case 'json':
      return typeof value === 'string' ? value : JSON.stringify(value);
    case 'string':
      return String(value);
  }
}

function listOrder(def: ResourceDef): string {
  if (def.listOrder) return def.listOrder;
  const timestamp = def.columns.find((column) => column.name.endsWith('_at'))?.name;
  return timestamp ? `${timestamp} DESC, ${def.idColumn}` : def.idColumn;
}

View on GitHub (pinned to 294ef2aee8)

Solutions

  1. Remove node_modules/.git/build output from the plugin directory
  2. Prune generated or cache directories before packaging
  3. Check MAX_PLUGIN_FILES in plugin-dir.ts for the exact cap and audit with 'find <dir> | wc -l'
Defensive patterns

Strategy: validation

Validate before calling

let count = 0;
const walk = (d: string) => {
  for (const e of fs.readdirSync(d, { withFileTypes: true })) {
    count += 1;
    if (e.isDirectory()) walk(path.join(d, e.name));
  }
};
walk(dir);
if (count > MAX_PLUGIN_FILES) { /* prune (node_modules, .git, caches) before walkPluginDir */ }

Try / catch

try { walkPluginDir(dir); } catch (e) { if (e instanceof Error && e.message.includes('more than') && e.message.includes('entries')) { /* clean the tree and retry */ } else throw e; }

Prevention

When it happens

Trigger: A plugin tree with more than MAX_PLUGIN_FILES total dirents across all directories.

Common situations: Committed node_modules, .git directories, build artifacts, or cache folders inside a template; generated assets ballooning file counts.

Related errors


AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28). Data as JSON: /api/errors/f91c57f7e053252e. Report an issue: GitHub.