multica-ai/multica · error

import cap exceeded

Error message

import cap exceeded

What it means

errImportCapExceeded is a sentinel wrapped by per-file/per-bundle limit errors during skill import: >1 MiB for a single file (maxImportFileSize), >8 MiB aggregate (maxImportTotalSize), or >256 supporting files (maxImportFileCount). The import must abort rather than silently drop files, because a truncated skill would look valid to the user. Callers detect it with isCapError (errors.Is) and return a permanent client error.

Source

Thrown at server/internal/handler/skill.go:624

// importedSkill holds the data extracted from an external source.
type importedSkill struct {
	name        string
	description string
	content     string // SKILL.md body
	files       []importedFile
	bundleSize  int            // running sum of file content bytes for cap enforcement
	origin      map[string]any // written into skill.config.origin so the UI can show provenance
}

type importedFile struct {
	path    string
	content string
}

// errImportCapExceeded marks an error caused by a per-file or per-bundle cap.
// Such errors must abort the import — silently dropping a file would otherwise
// produce an incomplete skill that looks valid to the user.
var errImportCapExceeded = errors.New("import cap exceeded")

// errImportSourceUnavailable marks a transient failure to read the upstream
// source (e.g. the GitHub tree API rate limiting). The import can't proceed
// safely but should be retried, so it maps to a retryable HTTP status rather
// than a permanent error.
var errImportSourceUnavailable = errors.New("import source temporarily unavailable")

// isCapError reports whether err is (or wraps) errImportCapExceeded.
func isCapError(err error) bool {
	return errors.Is(err, errImportCapExceeded)
}

// addFile appends a supporting file while enforcing the per-bundle caps. It
// returns an error when either the file count or aggregate byte budget would
// be exceeded so the caller fails the import instead of silently truncating.
//
// Binary files (images, fonts, archives) are silently skipped: their bytes
// can't survive a PG TEXT column (SQLSTATE 22021), and they're reference

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Reduce bundle size: exclude large files, prune vendored deps, tighten the import path filter
  2. Split the skill into multiple imports, each under the 1 MiB/file and 8 MiB/256-file caps
  3. Reference big assets by URL instead of inlining them into the skill bundle
Defensive patterns

Strategy: validation

Validate before calling

const MAX_FILE = 1 << 20, MAX_TOTAL = 8 << 20, MAX_COUNT = 256;
let total = 0;
for (const f of files) {
  if (f.content.length > MAX_FILE) throw new Error(`${f.path} exceeds 1 MiB per-file cap`);
  total += f.content.length;
  if (total > MAX_TOTAL) throw new Error('Bundle exceeds 8 MiB total cap');
}
if (files.length > MAX_COUNT) throw new Error('Bundle exceeds 256 file cap');

Try / catch

try { await importSkill(ref); }
catch (e) {
  if (e.status === 400 && /import cap/i.test(e.message)) planBundleReduction(); // permanent
  else throw e;
}

Prevention

When it happens

Trigger: POST a skill import from a GitHub repo whose bundle exceeds 8 MiB of supporting files or 256 files, or that contains a single file over 1 MiB (e.g. bundled WASM, large JSON fixtures, minified bundles).

Common situations: Importing a skill that vendors node_modules or large datasets; skills embedding model weights or embeddings; monorepo imports where path filtering is too broad.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/eb1e774e5a022e63. Report an issue: GitHub.