stablyai/orca · error

plugin exceeds the ${MAX_PLUGIN_FILES}-entry limit

Error message

plugin exceeds the ${MAX_PLUGIN_FILES}-entry limit

What it means

Thrown by the packaged plugin resource verifier when the recursive file count of a single plugin tree exceeds MAX_PLUGIN_FILES (2000). The counter increments for every directory entry visited (files, subdirectories, symlinks) and throws immediately when entriesVisited exceeds the limit. This is a size guardrail: a plugin with more than 2000 entries is likely packaging node_modules, build artifacts, or other unintended content.

Source

Thrown at config/scripts/verify-packaged-plugin-resources.cjs:30

}

function hashPackagedPluginTree(root) {
  const files = []
  let entriesVisited = 0
  let totalBytes = 0
  const visit = (directory) => {
    const entries = readdirSync(directory, { withFileTypes: true }).sort((left, right) =>
      left.name < right.name ? -1 : left.name > right.name ? 1 : 0
    )
    for (const entry of entries) {
      if (directory === root && entry.name === '.git') {
        continue
      }
      const entryPath = join(directory, entry.name)
      const metadata = lstatSync(entryPath)
      entriesVisited += 1
      if (entriesVisited > MAX_PLUGIN_FILES) {
        throw new Error(`plugin exceeds the ${MAX_PLUGIN_FILES}-entry limit`)
      }
      if (metadata.isSymbolicLink()) {
        throw new Error(`packaged plugin contains a symlink: ${relative(root, entryPath)}`)
      }
      if (metadata.isDirectory()) {
        visit(entryPath)
      } else if (metadata.isFile()) {
        totalBytes += metadata.size
        if (totalBytes > MAX_PLUGIN_TOTAL_BYTES) {
          throw new Error(`plugin exceeds the ${MAX_PLUGIN_TOTAL_BYTES}-byte limit`)
        }
        files.push({ path: entryPath, size: metadata.size })
      } else {
        throw new Error(`packaged plugin contains an unsupported entry: ${entryPath}`)
      }
    }
  }
  visit(root)

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Inspect the plugin directory tree: find <pluginRoot> -type f | wc -l to see the actual file count.
  2. Ensure the plugin packaging step excludes node_modules, dist, .git, and test directories.
  3. If the plugin legitimately needs many files, evaluate whether some can be bundled into a single file (e.g., pack data files into a tar/zip or inline them).
  4. If 2000 is genuinely too low for a valid plugin, raise MAX_PLUGIN_FILES in config/scripts/verify-packaged-plugin-resources.cjs:5 — but first confirm the extra files are intentional.
Defensive patterns

Strategy: validation

Validate before calling

// Before packaging, count files in the plugin directory.
const { execSync } = require('node:child_process')

function preCheckPluginFileCount(pluginRoot, maxFiles = 2000) {
  const output = execSync(`find ${JSON.stringify(pluginRoot)} -type f | wc -l`, {
    encoding: 'utf8'
  })
  const count = parseInt(output.trim(), 10)
  return { ok: count <= maxFiles, count, maxFiles }
}

Prevention

When it happens

Trigger: hashPackagedPluginTree(root) is called for a bundled plugin whose directory tree contains more than 2000 filesystem entries. This typically happens when a .gitignore or packaging exclusion is missing and node_modules, dist folders, test fixtures, or .git history are included in the packaged plugin.

Common situations: A plugin's packaging step forgot to exclude node_modules; a build artifact directory (dist/, build/) with many chunk files was included; a plugin bundles test fixtures or large datasets; symlinks from a development setup (pnpm, yarn workspaces) were dereferenced into many real files during packaging.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/fb365ff32d32ee4b. Report an issue: GitHub.