vxcontrol/pentagi · error

container file transfer failed: %w

Error message

container file transfer failed: %w

What it means

This is the real docker-side failure: CopyToContainer failed to stream the finished tar buffer into the flow container at filepath.Dir(path). Common wrapped causes are: no such container, container not running, no such directory in the container, path is not a directory, permission denied, or connection problems to the Docker daemon. It is raised by WriteFile and EditFile whenever the in-container destination directory is missing or inaccessible.

Source

Thrown at backend/pkg/tools/terminal.go:492

		return fmt.Errorf("tar archive header generation failed: %w", err)
	}

	_, err = archiveWriter.Write([]byte(content))
	if err != nil {
		return fmt.Errorf("tar archive content serialization failed: %w", err)
	}

	err = archiveWriter.Close()
	if err != nil {
		return fmt.Errorf("failed to close tar writer: %w", err)
	}

	dir := filepath.Dir(path)
	err = t.dockerClient.CopyToContainer(ctx, containerName, dir, tarBuffer, client.CopyToContainerOptions{
		AllowOverwriteDirWithFile: true,
	})
	if err != nil {
		return fmt.Errorf("container file transfer failed: %w", err)
	}

	return nil
}

// EditFile applies a unified diff to the file at path: it reads the current
// content, applies the diff to it entirely in memory (see applyUnifiedDiff),
// and only if every hunk applied cleanly writes the result back - a diff
// that doesn't fully apply leaves the file untouched.
func (t *terminal) EditFile(ctx context.Context, flowID int64, path, diffText string) (string, error) {
	if path == "" {
		return "", fmt.Errorf("path is required and cannot be empty")
	}
	if strings.TrimSpace(diffText) == "" {
		return "", fmt.Errorf("diff is required and cannot be empty")
	}

	current, err := t.readFileFromContainer(ctx, flowID, path)

View on GitHub (pinned to ea665308ba)

Solutions

  1. Create the parent directory inside the container first (e.g. exec `mkdir -p <dir>` via the terminal tool) before writing the file
  2. Confirm the container is running: docker ps / IsContainerRunning, and restart the flow container if it stopped
  3. Check that the destination path is not on a read-only mount and the container user has write permission
  4. Verify Docker daemon connectivity from the backend (docker info); fix DOCKER_HOST/socket permissions
  5. Inspect the wrapped %w cause for the exact Docker API error (e.g. 'no such directory', 'permission denied')

Example fix

// before
dir := filepath.Dir(path)
err = t.dockerClient.CopyToContainer(ctx, containerName, dir, tarBuffer, client.CopyToContainerOptions{
    AllowOverwriteDirWithFile: true,
})
// after
if err := t.ensureDirExists(ctx, containerName, filepath.Dir(path)); err != nil { // runs `mkdir -p` via exec
    return fmt.Errorf("failed to ensure directory %s: %w", filepath.Dir(path), err)
}
err = t.dockerClient.CopyToContainer(ctx, containerName, filepath.Dir(path), tarBuffer, client.CopyToContainerOptions{
    AllowOverwriteDirWithFile: true,
})
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the parent dir exists in the container before writing
out, err := term.ExecuteCommand(ctx, flowID, fmt.Sprintf("test -d %s && echo OK", filepath.Dir(path)))
if !strings.Contains(out, "OK") {
    if _, err := term.ExecuteCommand(ctx, flowID, fmt.Sprintf("mkdir -p %s", filepath.Dir(path))); err != nil {
        return err
    }
}

Try / catch

if _, err := term.WriteFile(ctx, flowID, content, path); err != nil {
    if strings.Contains(err.Error(), "container file transfer failed") {
        // inspect errors.Unwrap(err) for Docker API cause:
        // 'no such directory' → mkdir first; 'is not running' → restart container
    }
}

Prevention

When it happens

Trigger: Writing to a path whose parent directory does not exist in the container (CopyToContainer does not mkdir -p); writing into a read-only filesystem or a directory the container user cannot write; the flow container was stopped/removed between the IsContainerRunning check and the copy; Docker daemon connection drop.

Common situations: Agent tools writing to /tmp/subdir/file.txt where subdir was never created; writing to bind-mounted read-only volumes; container killed mid-flow; DOCKER_HOST misconfiguration or daemon restart.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/5ca01a4d90b4d81c. Report an issue: GitHub.