{"record":{"id":"86f7598b8718be62","repo":"agentscope-ai/agentscope","slug":"the-upload-contains-no-files","errorCode":null,"errorMessage":"The upload contains no files.","messagePattern":"The upload contains no files\\.","errorType":"exception","errorClass":"SkillUploadError","httpStatus":null,"severity":"error","filePath":"src/agentscope/app/_service/_workspace.py","lineNumber":368,"sourceCode":"    @staticmethod\n    def validate_manifest(manifest: UploadManifest, file_count: int) -> str:\n        \"\"\"Check a manifest and return the skill's root directory name.\n\n        Args:\n            manifest (`UploadManifest`): The declared upload contents.\n            file_count (`int`): How many parts actually arrived.\n\n        Returns:\n            `str`: The single top-level directory every path sits under.\n\n        Raises:\n            SkillUploadError: If a limit is exceeded, a path is unsafe,\n                the paths span more than one root, no ``SKILL.md`` is\n                present, or the parts do not match the manifest.\n        \"\"\"\n        entries = manifest.entries\n        if not entries:\n            raise SkillUploadError(\"The upload contains no files.\")\n        if file_count != len(entries):\n            raise SkillUploadError(\n                f\"The manifest lists {len(entries)} files but \"\n                f\"{file_count} were sent.\",\n            )\n        if len(entries) > MAX_FILE_COUNT:\n            raise SkillUploadError(\n                f\"A skill may hold at most {MAX_FILE_COUNT} files, \"\n                f\"got {len(entries)}.\",\n            )\n\n        total = 0\n        roots: set[str] = set()\n        for entry in entries:\n            if entry.size > MAX_FILE_BYTES:\n                raise SkillUploadError(\n                    f\"{entry.path!r} is {entry.size} bytes, over the \"\n                    f\"{MAX_FILE_BYTES}-byte per-file limit.\",","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/app/_service/_workspace.py#L350-L386","documentation":"SkillUploadError (a ValueError) raised by WorkspaceService.validate_manifest when the upload manifest contains zero entries. validate_manifest is the gatekeeper run by upload_skill before any bytes are streamed, so an empty folder pick is rejected up front rather than creating an empty skill.","triggerScenarios":"Calling upload_skill with a manifest whose entries list is empty — typically the browser folder picker returned no files, or the client built the manifest from an empty directory and sent it anyway.","commonSituations":"User picks an empty folder in the upload dialog; client-side code constructs UploadManifest(entries=[]) due to a filtering bug; folder contains only ignored/hidden files that the picker dropped.","solutions":["Check the picked folder actually contains files before building the manifest.","Ensure every file (especially SKILL.md) is included in entries — a filter that drops dotfiles or SKILL.md can leave entries empty.","If the folder is legitimately empty, ask the user to select the skill's root folder that contains SKILL.md."],"exampleFix":"# before\nmanifest = UploadManifest(entries=[])\nawait service.upload_skill(ws, manifest, stream)\n\n# after\nif not manifest.entries:\n    raise ValueError(\"Pick a folder containing at least SKILL.md\")\nawait service.upload_skill(ws, manifest, stream)","handlingStrategy":"validation","validationCode":"if not manifest.entries:\n    raise ValueError(\"Select a folder with at least SKILL.md before uploading\")","typeGuard":"def has_entries(m: UploadManifest) -> bool:\n    return len(m.entries) > 0","tryCatchPattern":"try:\n    await service.upload_skill(ws, manifest, stream)\nexcept SkillUploadError as e:\n    if \"no files\" in str(e):\n        # re-prompt user to pick a non-empty folder\n        ...","preventionTips":["Build the manifest from a directory scan right before upload.","Disable the upload button until entries is non-empty."],"tags":["upload","skill","validation","empty-manifest"],"backgroundTag":"empty-request-payload","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}