agentscope-ai/agentscope · error · SkillUploadError

The upload is bytes, over the -byte limit.

Error message

The upload is {total} bytes, over the {MAX_TOTAL_BYTES}-byte limit.

What it means

SkillUploadError raised when the summed entry.size values exceed MAX_TOTAL_BYTES (500 MiB). After per-file checks pass, validate_manifest totals the declared sizes and enforces the archive-wide ceiling that bounds sandbox disk and install-slot hold time.

Solutions

  1. Audit the folder's total size and prune or externalize the largest assets to object storage linked from SKILL.md.
  2. Apply the same SKIP-list/exclusion approach as for file count (node_modules, build artifacts).
  3. If genuinely needed, negotiate a higher MAX_TOTAL_BYTES on the server.

Example fix

# before
total = sum(s for _, s in files)

# after
MAX_TOTAL = 500 * 1024 * 1024
total = sum(s for _, s in files)
if total > MAX_TOTAL:
    raise ValueError(f"Skill too large: {total} bytes; externalize large assets")
Defensive patterns

Strategy: validation

Validate before calling

MAX_TOTAL = 500 * 1024 * 1024
total = sum(e.size for e in manifest.entries)
if total > MAX_TOTAL:
    raise ValueError(f"Total {total} bytes exceeds {MAX_TOTAL}")

Prevention

When it happens

Trigger: Uploading a skill whose declared contents total more than 500 MiB — many moderately large assets (models, media, datasets) accumulating past the cap.

Common situations: Shipping weights or media alongside code; growing skill repos that creep past the limit over time; forgetting that the total counts all files, not just code.

Related errors


AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28). Data as JSON: /api/errors/830829c4f6c98b1a. Report an issue: GitHub.

Appendix: source

Thrown at src/agentscope/app/_service/_workspace.py:398

        total = 0
        roots: set[str] = set()
        for entry in entries:
            if entry.size > MAX_FILE_BYTES:
                raise SkillUploadError(
                    f"{entry.path!r} is {entry.size} bytes, over the "
                    f"{MAX_FILE_BYTES}-byte per-file limit.",
                )
            total += entry.size

            parts = entry.path.replace("\\", "/").split("/")
            if len(parts) < 2 or any(p in ("", ".", "..") for p in parts):
                raise SkillUploadError(f"Unsafe upload path: {entry.path!r}")
            if entry.path.startswith("/"):
                raise SkillUploadError(f"Unsafe upload path: {entry.path!r}")
            roots.add(parts[0])

        if total > MAX_TOTAL_BYTES:
            raise SkillUploadError(
                f"The upload is {total} bytes, over the "
                f"{MAX_TOTAL_BYTES}-byte limit.",
            )
        if len(roots) != 1:
            raise SkillUploadError(
                f"A skill must be a single folder, got {sorted(roots)}.",
            )

        root = roots.pop()
        if not any(e.path == f"{root}/SKILL.md" for e in manifest.entries):
            raise SkillUploadError(f"No SKILL.md at the root of {root!r}.")
        return root

    async def install_skill(
        self,
        workspace: WorkspaceBase,
        stream: AsyncIterator[bytes],
        archive_format: Literal["zip", "tar", "tar.gz"],

View on GitHub (pinned to e90f1c7592)