{"record":{"id":"562560c0be481fa7","repo":"agentscope-ai/agentscope","slug":"failed-to-expand-skill-archive-result-stderr-dec-562560","errorCode":null,"errorMessage":"Failed to expand skill archive: {result.stderr.decode('utf-8', 'replace')}","messagePattern":"Failed to expand skill archive: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/agentscope/workspace/_local_workspace.py","lineNumber":923,"sourceCode":"            self.workdir,\n            f\".skill-staging-{_generate_id()}\",\n        )\n        archive_path = f\"{staging}.{'tar.gz' if fmt == 'tar.gz' else fmt}\"\n        try:\n            await self._backend.write_stream(archive_path, stream)\n            result = await self._backend.exec_shell(\n                [\n                    self._python_command,\n                    \"-c\",\n                    _EXTRACT_ARCHIVE_SHIM,\n                    archive_path,\n                    staging,\n                    fmt,\n                    str(max_extracted_bytes),\n                ],\n            )\n            if not result.ok():\n                raise RuntimeError(\n                    f\"Failed to expand skill archive: \"\n                    f\"{result.stderr.decode('utf-8', 'replace')}\",\n                )\n            await self.add_skill(\n                await self._find_skill_root(staging),\n                agent_id=agent_id,\n            )\n        finally:\n            await self._backend.delete_path(staging)\n            await self._backend.delete_path(archive_path)\n\n    async def remove_skill(\n        self,\n        name: str,\n        *,\n        agent_id: str | None = None,\n    ) -> None:\n        \"\"\"Remove a skill from the workspace by its agent-facing name.","sourceCodeStart":905,"sourceCodeEnd":941,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/workspace/_local_workspace.py#L905-L941","documentation":"Raised by add_skill_archive when the subprocess used to extract the uploaded archive (into a staging directory, with a byte cap) exits non-zero. The RuntimeError wraps the extractor's stderr, so the message tells you why unpacking failed: unsupported format, corrupt archive, or extraction size limit exceeded.","triggerScenarios":"Calling add_skill_archive with a corrupt/truncated archive, an archive format not supported by the extractor (fmt mismatch), or an archive whose extracted contents exceed max_extracted_bytes (deflate bombs / large skills).","commonSituations":"Uploading .zip files renamed to .tar.gz, archives created with exotic compression (e.g. zstd) unsupported by the extractor, truncated uploads, or hitting the configured extraction byte limit with large model files inside the skill.","solutions":["Re-create the archive with a standard format matching fmt (e.g. tar czf skill.tar.gz skill-dir) and retry.","Read result.stderr in the exception message to identify the exact extractor failure (format vs size limit).","If the archive is legitimately large, raise max_extracted_bytes when calling add_skill_archive.","Verify archive integrity locally (tar -tzf skill.tar.gz / unzip -t skill.zip) before uploading."],"exampleFix":"# before\nawait ws.add_skill_archive(data, fmt=\"tar.gz\")  # stderr: 'unsupported format'\n\n# after\nimport tarfile, io\nbuf = io.BytesIO()\nwith tarfile.open(fileobj=buf, mode=\"w:gz\") as tf:\n    tf.add(\"my-skill\")\nawait ws.add_skill_archive(buf.getvalue(), fmt=\"tar.gz\")","handlingStrategy":"try-catch","validationCode":"import tarfile, zipfile\n\ndef archive_is_sound(data: bytes, fmt: str) -> bool:\n    import io\n    if fmt == \"zip\":\n        return zipfile.ZipFile(io.BytesIO(data)).testzip() is None\n    with tarfile.open(fileobj=io.BytesIO(data), mode=\"r:*\") as tf:\n        return len(tf.getnames()) > 0","typeGuard":null,"tryCatchPattern":"try:\n    await ws.add_skill_archive(data, fmt=fmt)\nexcept RuntimeError as e:\n    if \"Failed to expand skill archive\" in str(e):\n        raise SkillArchiveError(str(e)) from e\n    raise","preventionTips":["Test archives locally (tar -tzf / unzip -t) before upload.","Create archives with standard gzip/zip, not exotic compressors.","Size the archive and pass a matching max_extracted_bytes."],"tags":["agentscope","archive","extraction","tar","zip","workspace"],"backgroundTag":"archive-extraction-failed","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}