agentscope-ai/agentscope · error · SkillUploadError
{entry.path!r} is larger than its declared {entry.size} byte
Error message
{entry.path!r} is larger than its declared {entry.size} bytes. What it means
Raised by tar_stream in the workspace service when the bytes actually read from the upload stream for a file exceed the size declared in the manifest (TarInfo) for that entry. It is a SkillUploadError that aborts a streaming skill upload because the tar payload would be malformed (the tar header would no longer match the file data). It protects the server from writing corrupt archives.
Source
Thrown at src/agentscope/app/_service/_workspace.py:471
Yields:
`bytes`: The next chunk of the tar archive.
Raises:
SkillUploadError: If a part's real length differs from its
declared size.
"""
for entry, upload in zip(manifest.entries, files):
info = tarfile.TarInfo(name=entry.path)
info.size = entry.size
info.mtime = 0
yield info.tobuf(tarfile.GNU_FORMAT)
written = 0
while chunk := await upload.read(_CHUNK_SIZE):
written += len(chunk)
if written > entry.size:
raise SkillUploadError(
f"{entry.path!r} is larger than its declared "
f"{entry.size} bytes.",
)
yield chunk
if written != entry.size:
raise SkillUploadError(
f"{entry.path!r} declared {entry.size} bytes but "
f"sent {written}.",
)
padding = -entry.size % _TAR_BLOCK
if padding:
yield b"\0" * padding
# Two zero blocks mark the end of a tar archive.
yield b"\0" * (2 * _TAR_BLOCK)
# ── Git status ─────────────────────────────────────────────────────View on GitHub (pinned to e90f1c7592)
Solutions
- Recompute the manifest entry sizes immediately before uploading so entry.size matches the actual file length
- Ensure the skill directory is not being written to (close logs, stop generators) during the upload
- If files change frequently, snapshot/copy the skill directory to a temp location and build both manifest and stream from the snapshot
- In tests, assert your fixture's declared size equals len(payload) before calling upload_skill
Example fix
# before info.size = 100 # hardcoded / stale info = _tar_info(entry, size=100) # after size = entry_path.stat().st_size # measured right before streaming info = _tar_info(entry, size=size)
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def check_sizes(base: Path, entries) -> None:
for e in entries:
actual = (base / e.path).stat().st_size
if actual != e.size:
raise RuntimeError(f"{e.path}: manifest says {e.size}, disk has {actual}; rebuild manifest") Try / catch
try:
await upload_skill(...)
except SkillUploadError as e:
if "larger than its declared" in str(e):
rebuild_manifest_and_retry() # sizes drifted; recompute and re-upload Prevention
- Build the manifest and the byte stream from the same snapshot of the directory
- Freeze/lock skill directories (no concurrent writers) during upload
- In tests, assert declared size == len(payload) before invoking upload_skill
When it happens
Trigger: Calling upload_skill (or otherwise consuming tar_stream) where a manifest entry declares entry.size smaller than the real byte length of the corresponding file. Happens when the file changes on disk between manifest creation and streaming, or when the manifest is built with stale/wrong sizes (e.g. stat before truncation, off-by-one size computation, or reusing a manifest across uploads).
Common situations: Skill directory being mutated concurrently (logs written during upload), generating the manifest from metadata that doesn't match the actual file, unit tests that declare a smaller size than the payload they feed (test_declared_size_is_verified).
Related errors
- {entry.path!r} declared {entry.size} bytes but sent {written
- "AgentScope streaming model yielded no chunks."
- Cannot append DataBlock with URL source or different source
- unsafe tar member: ' + m.name
- not found in Pod: {path}
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/dab80002a0c12aa2.
Report an issue: GitHub.