moeru-ai/airi · error · Error
Extension package exceeds the
Error message
Extension package exceeds the ${extensionPackageLimits.entries} entry limit. What it means
During the breadth-first walk of the extension directory, every entry increments a counter; once it exceeds extensionPackageLimits.entries the import is aborted. The cap prevents pathological or hostile packages with enormous file counts from exhausting the walker.
Solutions
- Remove unneeded directories (node_modules, .git, dist caches) from the extension folder before importing.
- Import only the package source/root that contains the manifest, not the whole workspace.
- Ship the extension as a curated set of files and check the entry count before importing.
- If the package legitimately needs more entries, split it into multiple extensions.
Example fix
// before
await staged('my-workspace/') // includes node_modules (100k+ entries) -> throws
// after: prune before import
await stageCleanup('my-workspace/') // rm -rf node_modules .git dist
await staged('my-workspace/') Defensive patterns
Strategy: validation
Validate before calling
import { readdir } from 'node:fs/promises'
import { join } from 'node:path'
async function countEntries(dir: string): Promise<number> {
let n = 0
for (const entry of await readdir(dir, { withFileTypes: true })) {
n += 1
if (entry.isDirectory()) n += await countEntries(join(dir, entry.name))
}
return n
}
// countEntries(folder) should stay below extensionPackageLimits.entries Try / catch
try {
await staged(folder)
} catch (error) {
if (error instanceof Error && error.message.includes('entry limit')) {
showUserError('Package has too many files; remove node_modules/.git/build caches and retry.')
return
}
throw error
} Prevention
- Prune node_modules, .git, and build caches from any folder before importing.
- Import the package root containing the manifest, never a whole workspace.
- Count files with `find <dir> | wc -l` before importing large packages.
When it happens
Trigger: Calling inspectExtensionDirectory on a folder whose total file+directory entry count (recursively, including node_modules-like trees) exceeds extensionPackageLimits.entries.
Common situations: Importing a folder that accidentally contains node_modules, .git objects, or build-output artifacts; importing an unpacked package with thousands of small files; a generator emitted an absurdly deep/wide tree.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- Extension package exceeds the 512 MiB size limit.
- Extension packages can contain only files and directories
- Extension source must be a regular directory
- Extension manifest does not exist
- Extension manifest is invalid
AI-assisted analysis of moeru-ai/airi@438a067dde (2026-09-17).
Data as JSON: /api/errors/64169e323480c258.
Report an issue: GitHub.
Appendix: source
Thrown at apps/stage-tamagotchi/src/main/services/airi/plugins/host/directory-import.ts:176
const sourceRealPath = await realpath(sourcePath)
const manifestPath = join(sourceRealPath, extensionManifestFileName)
await assertRegularFile(manifestPath, 'Extension manifest')
const files: Array<{ path: string, relativePath: string, size: number }> = []
const directories = ['.']
const pendingDirectories = [sourceRealPath]
let entryCount = 0
let totalBytes = 0
while (pendingDirectories.length > 0) {
const directory = pendingDirectories.pop()
if (!directory) {
continue
}
const entries = await opendir(directory)
for await (const entry of entries) {
entryCount += 1
if (entryCount > extensionPackageLimits.entries) {
throw new Error(`Extension package exceeds the ${extensionPackageLimits.entries} entry limit.`)
}
const path = join(directory, entry.name)
const stats = await lstat(path)
const relativePath = relative(sourceRealPath, path)
if (stats.isSymbolicLink()) {
throw new Error(`Extension packages cannot contain symbolic links: ${relativePath}`)
}
if (stats.isDirectory()) {
directories.push(relativePath)
pendingDirectories.push(path)
continue
}
if (!stats.isFile()) {
throw new Error(`Extension packages can contain only files and directories: ${relativePath}`)
}
totalBytes += stats.size
if (totalBytes > extensionPackageLimits.totalBytes) {View on GitHub (pinned to 438a067dde)