vxcontrol/pentagi · error
failed to read list output for '%s': %w
Error message
failed to read list output for '%s': %w
What it means
demuxExecStdout reads the multiplexed exec stream and its error is wrapped with this message. Failures include a truncated frame (ErrUnexpectedEOF mid-header/frame), stdout exceeding the byte cap, or a daemon-injected systemerr frame. In all cases the listing is considered incomplete and is discarded rather than served partially.
Source
Thrown at backend/pkg/docker/client.go:1003
// including a \n that is part of a filename — corrupting the name. Without a
// TTY the exec stream is multiplexed and demuxed below.
createResp, err := dc.ContainerExecCreate(ctx, containerID, client.ExecCreateOptions{
Cmd: []string{"find", dirPath, "-maxdepth", "1", "-mindepth", "1", "!", "-name", ".*", "-print0"},
AttachStdout: true,
AttachStderr: true,
})
if err != nil {
return ContainerDirListing{}, fmt.Errorf("failed to create list exec for '%s': %w", dirPath, err)
}
resp, err := dc.ContainerExecAttach(ctx, createResp.ID, client.ExecAttachOptions{})
if err != nil {
return ContainerDirListing{}, fmt.Errorf("failed to attach list exec for '%s': %w", dirPath, err)
}
output, readErr := demuxExecStdout(resp.Reader, maxListStdoutBytes)
resp.Close()
if readErr != nil {
return ContainerDirListing{}, fmt.Errorf("failed to read list output for '%s': %w", dirPath, readErr)
}
inspect, err := dc.ContainerExecInspect(ctx, createResp.ID)
if err != nil {
return ContainerDirListing{}, fmt.Errorf("failed to inspect list exec for '%s': %w", dirPath, err)
}
if inspect.ExitCode != 0 {
return ContainerDirListing{}, fmt.Errorf("list command failed for '%s' with exit code %d: %s", dirPath, inspect.ExitCode, string(output))
}
entryPaths, truncated := parseFindEntries(output)
stats, failures := statContainerEntries(ctx, entryPaths, containerListWorkers, func(ctx context.Context, entryPath string) (container.PathStat, error) {
return dc.ContainerStatPath(ctx, containerID, entryPath)
})
// A cancelled context is a directory-level fault (the client is gone), not a
// partial listing, so surface it as an error. Entries that individually failedView on GitHub (pinned to ea665308ba)
Solutions
- List a narrower subdirectory instead of a huge parent (reduce output below the cap)
- Retry the listing if the cause was a transient stream reset
- Check why the container exited mid-exec (OOM, kill signal) via `docker inspect`
- If the cap is legitimately too small for your workload, raise maxListStdoutBytes
Example fix
// before: giant dir overflows the cap listing, err := dc.ListContainerDir(ctx, id, "/") // after: list the intended subtree listing, err := dc.ListContainerDir(ctx, id, "/workspace/src")
Defensive patterns
Strategy: retry
Try / catch
listing, err := client.ListContainerDir(ctx, containerID, dir)
if err != nil {
if strings.Contains(err.Error(), "failed to read list output") {
// stream read failed: retry or narrow the directory
return retryListing(ctx, containerID, dir)
}
return err
} Prevention
- List narrow directories rather than huge trees
- Keep containers alive and un-OOM'd during listings
- Avoid flaky proxies between client and daemon
- Tune maxListStdoutBytes to expected workload
When it happens
Trigger: The exec stream ends mid-frame (connection reset, daemon killed the stream, container OOM-killed while find was writing), the directory listing produces more than maxListStdoutBytes of stdout, or Docker injects a systemerr frame (stream id 3).
Common situations: Listing a huge directory (node_modules, /usr, /proc) blowing the output cap; container killed mid-exec; flaky connection to a remote Docker daemon; sandboxed workload deliberately flooding output.
Related errors
- failed to attach list exec for '%s': %w
- truncated exec stream: %w
- listing output exceeded %d bytes
- docker exec systemerr: %s
- failed to copy output: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/c40605988da5d0bf.
Report an issue: GitHub.