vxcontrol/pentagi · error
failed to create list exec for '%s': %w
Error message
failed to create list exec for '%s': %w
What it means
ListContainerDir runs `find <dir> -maxdepth 1 -print0` inside the container via a Docker exec. This error wraps a failure of the ContainerExecCreate API call, meaning the exec process could not even be created in the target container. It is thrown before any output is read, so the listing is entirely unavailable. The wrapped cause (Docker API error) is preserved via %w.
Source
Thrown at backend/pkg/docker/client.go:993
if !dirStat.Mode.IsDir() {
return ContainerDirListing{}, fmt.Errorf("container path '%s' is not a directory", dirPath)
}
// List direct children NUL-delimited. Parsing `ls` output is unsafe: under a
// TTY GNU coreutils shell-quotes names and busybox wraps them in ANSI escapes,
// so a readable file with a space / quote / non-ASCII byte would be mis-stat'd
// and reported unreadable. `find -print0` emits literal bytes and is portable
// (GNU + busybox); the NUL delimiter also survives names containing newlines.
// No TTY: a TTY's onlcr would rewrite every \n in the stream to \r\n —
// 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))View on GitHub (pinned to ea665308ba)
Solutions
- Verify the container is running: `docker inspect -f '{{.State.Running}}' <containerID>` and use the correct ID
- Recreate/restart the container and retry the listing
- Ensure the image contains a `find` binary (add busybox/coreutils to the Dockerfile)
- Check Docker daemon connectivity (`docker ps` from the host running the code)
Example fix
// before: exec fails because container is stopped
listing, err := dc.ListContainerDir(ctx, deadContainerID, "/work")
// after: guard on container state before listing
state, _ := dc.ContainerInspect(ctx, containerID)
if !state.State.Running {
return fmt.Errorf("container %s not running", containerID)
}
listing, err := dc.ListContainerDir(ctx, containerID, "/work") Defensive patterns
Strategy: retry
Validate before calling
state, err := dc.ContainerInspect(ctx, containerID)
if err != nil || !state.State.Running {
return fmt.Errorf("container %s not listable", containerID)
} Try / catch
listing, err := client.ListContainerDir(ctx, containerID, dir)
if err != nil {
var derr *dockerUnknownContainer
if errors.As(err, &derr) { /* container gone — recreate */ }
return err
} Prevention
- Check container state (running) before exec-based operations
- Use stable container names/IDs and refresh them after restarts
- Ensure images include busybox/coreutils so `find` exists
- Monitor daemon health before batch operations
When it happens
Trigger: Calling ListContainerDir(ctx, containerID, dirPath) when the container is stopped/removed, the containerID is wrong, the image lacks a `find` binary (no PATH exec resolution), the Docker daemon is unreachable, or the API request is rejected (404 no such container, 409 container not running).
Common situations: Container exited or was reaped between stat and exec; typo'd or stale container ID; minimal images (distroless, scratch) without coreutils/busybox `find`; Docker daemon restarted or socket permissions changed mid-flow.
Related errors
- container shutdown failed: %w
- failed to stop container: %w
- failed to remove container: %w
- failed to stat container path '%s': %w
- failed to attach list exec for '%s': %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/f150a11c09dd88a7.
Report an issue: GitHub.