FoundationAgents/OpenManus · error · RuntimeError

Failed to extract file content

Error message

Failed to extract file content

What it means

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.

Source

Thrown at app/sandbox/core/sandbox.py:421

        Returns:
            File content.

        Raises:
            RuntimeError: If read operation fails.
        """
        with tempfile.NamedTemporaryFile() as tmp:
            for chunk in tar_stream:
                tmp.write(chunk)
            tmp.seek(0)

            with tarfile.open(fileobj=tmp) as tar:
                member = tar.next()
                if not member:
                    raise RuntimeError("Empty tar archive")

                file_content = tar.extractfile(member)
                if not file_content:
                    raise RuntimeError("Failed to extract file content")

                return file_content.read()

    async def cleanup(self) -> None:
        """Cleans up sandbox resources."""
        errors = []
        try:
            if self.terminal:
                try:
                    await self.terminal.close()
                except Exception as e:
                    errors.append(f"Terminal cleanup error: {e}")
                finally:
                    self.terminal = None

            if self.container:
                try:
                    await asyncio.to_thread(self.container.stop, timeout=5)

View on GitHub (pinned to 52a13f2a57)

Solutions

  1. Iterate members and pick the first regular file: use member.isfile() instead of blindly taking tar.next().
  2. Validate at the call site that the source path is a file ('test -f <path>') and reject directories with a clear message before archiving.
  3. If you intentionally need directories, switch to a directory-aware path (archive every member recursively) rather than single-member extraction.

Example fix

# before
member = tar.next()
if not member:
    raise RuntimeError("Empty tar archive")
file_content = tar.extractfile(member)
if not file_content:
    raise RuntimeError("Failed to extract file content")

# after
member = None
for m in tar:
    if m.isfile():
        member = m
        break
if member is None:
    raise RuntimeError("Archive contains no regular file (directory or symlink only)")
file_content = tar.extractfile(member)
Defensive patterns

Strategy: validation

Validate before calling

rc, _, _ = await sandbox.run_command(f'test -f {shlex.quote(path)}')
if rc != 0:
    raise ValueError(f'{path} is not a regular file; refusing single-file extraction')

Type guard

import tarfile

def first_regular_member(tar: tarfile.TarFile) -> tarfile.TarInfo | None:
    return next((m for m in tar if m.isfile()), None)

Try / catch

try:
    data = extract_from_tar(stream)
except RuntimeError as e:
    if 'Failed to extract file content' in str(e):
        raise RuntimeError('Source is a directory or symlink; give a regular-file path') from e
    raise

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

Related errors


AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15). Data as JSON: /api/errors/dff99d7cb1ecabcc. Report an issue: GitHub.