{"record":{"id":"019dfe09e2fcb4e2","repo":"bytedance/deer-flow","slug":"skill-archive-member-is-too-large-to-preview","errorCode":null,"errorMessage":"Skill archive member is too large to preview","messagePattern":"Skill archive member is too large to preview","errorType":"http","errorClass":"HTTPException","httpStatus":413,"severity":"warning","filePath":"backend/app/gateway/routers/artifacts.py","lineNumber":221,"sourceCode":"    )\n    return ranged_content, 206, headers\n\n\ndef is_text_file_by_content(path: Path, sample_size: int = 8192) -> bool:\n    \"\"\"Check if file is text by examining content for null bytes.\"\"\"\n    try:\n        with open(path, \"rb\") as f:\n            chunk = f.read(sample_size)\n            # Text files shouldn't contain null bytes\n            return b\"\\x00\" not in chunk\n    except Exception:\n        return False\n\n\ndef _read_skill_archive_member(zip_ref: zipfile.ZipFile, info: zipfile.ZipInfo) -> bytes:\n    \"\"\"Read a .skill archive member while enforcing an uncompressed size cap.\"\"\"\n    if info.file_size > MAX_SKILL_ARCHIVE_MEMBER_BYTES:\n        raise HTTPException(status_code=413, detail=\"Skill archive member is too large to preview\")\n\n    chunks: list[bytes] = []\n    total_read = 0\n    with zip_ref.open(info, \"r\") as src:\n        while chunk := src.read(_SKILL_ARCHIVE_READ_CHUNK_SIZE):\n            total_read += len(chunk)\n            if total_read > MAX_SKILL_ARCHIVE_MEMBER_BYTES:\n                raise HTTPException(status_code=413, detail=\"Skill archive member is too large to preview\")\n            chunks.append(chunk)\n    return b\"\".join(chunks)\n\n\ndef _extract_file_from_skill_archive(zip_path: Path, internal_path: str) -> bytes | None:\n    \"\"\"Extract a file from a .skill ZIP archive.\n\n    Args:\n        zip_path: Path to the .skill file (ZIP archive).\n        internal_path: Path to the file inside the archive (e.g., \"SKILL.md\").","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/artifacts.py#L203-L239","documentation":"HTTP 413 from _read_skill_archive_member: the ZIP entry's declared uncompressed file_size in its ZipInfo header exceeds MAX_SKILL_ARCHIVE_MEMBER_BYTES (16 MiB, artifacts.py:38). The header check happens before any decompression so a zip-bomb-sized member is refused without spending CPU/bytes on it.","triggerScenarios":"GET artifact preview for a .skill archive whose member (e.g. bundled model, dataset, or vendored dependency) declares >16 MiB uncompressed size in the ZIP central directory.","commonSituations":"Skill packs vendoring large binaries or node_modules-like trees, users zipping whole working directories into .skill files, malicious/naive archives with inflated headers.","solutions":["Remove the oversized member from the skill pack and rebuild the .skill archive","Split large assets out of the skill; reference them by URL or install step instead of bundling","If you are the consumer, preview other members — only the oversized entry is refused"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import zipfile\n\nMAX_SKILL_ARCHIVE_MEMBER_BYTES = 16 * 1024 * 1024\n\ndef member_within_cap(zip_path: str, internal_path: str) -> bool:\n    with zipfile.ZipFile(zip_path) as z:\n        return z.getinfo(internal_path).file_size <= MAX_SKILL_ARCHIVE_MEMBER_BYTES","typeGuard":null,"tryCatchPattern":"if resp.status_code == 413 and \"skill archive member\" in resp.text.lower():\n    skip_preview(internal_path)  # show metadata only","preventionTips":["Keep skill-pack members under 16 MiB; bundle code and prompts, not datasets","Validate .skill archives at build time with a size audit step","Never trust declared sizes when unpacking untrusted archives yourself — the Gateway already enforces the cap for previews"],"tags":["api","artifacts","skills","zip","http-413","limits"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}