{"record":{"id":"dff99d7cb1ecabcc","repo":"FoundationAgents/OpenManus","slug":"failed-to-extract-file-content","errorCode":null,"errorMessage":"Failed to extract file content","messagePattern":"Failed to extract file content","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"app/sandbox/core/sandbox.py","lineNumber":421,"sourceCode":"        Returns:\n            File content.\n\n        Raises:\n            RuntimeError: If read operation fails.\n        \"\"\"\n        with tempfile.NamedTemporaryFile() as tmp:\n            for chunk in tar_stream:\n                tmp.write(chunk)\n            tmp.seek(0)\n\n            with tarfile.open(fileobj=tmp) as tar:\n                member = tar.next()\n                if not member:\n                    raise RuntimeError(\"Empty tar archive\")\n\n                file_content = tar.extractfile(member)\n                if not file_content:\n                    raise RuntimeError(\"Failed to extract file content\")\n\n                return file_content.read()\n\n    async def cleanup(self) -> None:\n        \"\"\"Cleans up sandbox resources.\"\"\"\n        errors = []\n        try:\n            if self.terminal:\n                try:\n                    await self.terminal.close()\n                except Exception as e:\n                    errors.append(f\"Terminal cleanup error: {e}\")\n                finally:\n                    self.terminal = None\n\n            if self.container:\n                try:\n                    await asyncio.to_thread(self.container.stop, timeout=5)","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/FoundationAgents/OpenManus/blob/52a13f2a57d8c7f6737eefb02ccf569594d44273/app/sandbox/core/sandbox.py#L403-L439","documentation":"tar.extractfile(member) returned None, which only happens when the first tar member is not a regular file — directories, symlinks, devices, and fifos have no extractable content stream. Since the code extracts tar.next() (the first member) unconditionally, getting the container to archive a directory or a symlink as the leading member triggers this.","triggerScenarios":"Calling the copy/read helper with a path that is a directory: docker get_archive returns the directory entry as the first member and extractfile() yields None for it. Same for a symlink path. Also hit when copying '/workspace' instead of '/workspace/file.txt'.","commonSituations":"Agent or user passes a folder path (e.g. an output directory) to a file-copy API; a generated file is actually a symlink created by a build step inside the container.","solutions":["Iterate members and pick the first regular file: use member.isfile() instead of blindly taking tar.next().","Validate at the call site that the source path is a file ('test -f <path>') and reject directories with a clear message before archiving.","If you intentionally need directories, switch to a directory-aware path (archive every member recursively) rather than single-member extraction."],"exampleFix":"# before\nmember = tar.next()\nif not member:\n    raise RuntimeError(\"Empty tar archive\")\nfile_content = tar.extractfile(member)\nif not file_content:\n    raise RuntimeError(\"Failed to extract file content\")\n\n# after\nmember = None\nfor m in tar:\n    if m.isfile():\n        member = m\n        break\nif member is None:\n    raise RuntimeError(\"Archive contains no regular file (directory or symlink only)\")\nfile_content = tar.extractfile(member)","handlingStrategy":"validation","validationCode":"rc, _, _ = await sandbox.run_command(f'test -f {shlex.quote(path)}')\nif rc != 0:\n    raise ValueError(f'{path} is not a regular file; refusing single-file extraction')","typeGuard":"import tarfile\n\ndef first_regular_member(tar: tarfile.TarFile) -> tarfile.TarInfo | None:\n    return next((m for m in tar if m.isfile()), None)","tryCatchPattern":"try:\n    data = extract_from_tar(stream)\nexcept RuntimeError as e:\n    if 'Failed to extract file content' in str(e):\n        raise RuntimeError('Source is a directory or symlink; give a regular-file path') from e\n    raise","preventionTips":["Validate 'test -f <path>' in the container before copying.","Prefer member.isfile() over tar.next() when extracting.","Resolve symlinks in the container ('readlink -f') before archiving."],"tags":["tar","docker","symlink","directory"],"backgroundTag":null,"analyzedSha":"52a13f2a57d8c7f6737eefb02ccf569594d44273","analyzedAt":"2026-08-15T02:33:49.993Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}