{"record":{"id":"eb1e774e5a022e63","repo":"multica-ai/multica","slug":"import-cap-exceeded","errorCode":null,"errorMessage":"import cap exceeded","messagePattern":"import cap exceeded","errorType":"error_code","errorClass":null,"httpStatus":413,"severity":"error","filePath":"server/internal/handler/skill.go","lineNumber":624,"sourceCode":"// importedSkill holds the data extracted from an external source.\ntype importedSkill struct {\n\tname        string\n\tdescription string\n\tcontent     string // SKILL.md body\n\tfiles       []importedFile\n\tbundleSize  int            // running sum of file content bytes for cap enforcement\n\torigin      map[string]any // written into skill.config.origin so the UI can show provenance\n}\n\ntype importedFile struct {\n\tpath    string\n\tcontent string\n}\n\n// errImportCapExceeded marks an error caused by a per-file or per-bundle cap.\n// Such errors must abort the import — silently dropping a file would otherwise\n// produce an incomplete skill that looks valid to the user.\nvar errImportCapExceeded = errors.New(\"import cap exceeded\")\n\n// errImportSourceUnavailable marks a transient failure to read the upstream\n// source (e.g. the GitHub tree API rate limiting). The import can't proceed\n// safely but should be retried, so it maps to a retryable HTTP status rather\n// than a permanent error.\nvar errImportSourceUnavailable = errors.New(\"import source temporarily unavailable\")\n\n// isCapError reports whether err is (or wraps) errImportCapExceeded.\nfunc isCapError(err error) bool {\n\treturn errors.Is(err, errImportCapExceeded)\n}\n\n// addFile appends a supporting file while enforcing the per-bundle caps. It\n// returns an error when either the file count or aggregate byte budget would\n// be exceeded so the caller fails the import instead of silently truncating.\n//\n// Binary files (images, fonts, archives) are silently skipped: their bytes\n// can't survive a PG TEXT column (SQLSTATE 22021), and they're reference","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/handler/skill.go#L606-L642","documentation":"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.","triggerScenarios":"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).","commonSituations":"Importing a skill that vendors node_modules or large datasets; skills embedding model weights or embeddings; monorepo imports where path filtering is too broad.","solutions":["Reduce bundle size: exclude large files, prune vendored deps, tighten the import path filter","Split the skill into multiple imports, each under the 1 MiB/file and 8 MiB/256-file caps","Reference big assets by URL instead of inlining them into the skill bundle"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const MAX_FILE = 1 << 20, MAX_TOTAL = 8 << 20, MAX_COUNT = 256;\nlet total = 0;\nfor (const f of files) {\n  if (f.content.length > MAX_FILE) throw new Error(`${f.path} exceeds 1 MiB per-file cap`);\n  total += f.content.length;\n  if (total > MAX_TOTAL) throw new Error('Bundle exceeds 8 MiB total cap');\n}\nif (files.length > MAX_COUNT) throw new Error('Bundle exceeds 256 file cap');","typeGuard":null,"tryCatchPattern":"try { await importSkill(ref); }\ncatch (e) {\n  if (e.status === 400 && /import cap/i.test(e.message)) planBundleReduction(); // permanent\n  else throw e;\n}","preventionTips":["Pre-scan repo trees for file sizes before importing","Exclude vendored dirs, weights, and datasets from import paths","Reference large assets by URL instead of inlining"],"tags":["import","limits","skills","size-caps"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}