{"record":{"id":"f150a11c09dd88a7","repo":"vxcontrol/pentagi","slug":"failed-to-create-list-exec-for-s-w","errorCode":null,"errorMessage":"failed to create list exec for '%s': %w","messagePattern":"failed to create list exec for '(.+?)': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/docker/client.go","lineNumber":993,"sourceCode":"\tif !dirStat.Mode.IsDir() {\n\t\treturn ContainerDirListing{}, fmt.Errorf(\"container path '%s' is not a directory\", dirPath)\n\t}\n\n\t// List direct children NUL-delimited. Parsing `ls` output is unsafe: under a\n\t// TTY GNU coreutils shell-quotes names and busybox wraps them in ANSI escapes,\n\t// so a readable file with a space / quote / non-ASCII byte would be mis-stat'd\n\t// and reported unreadable. `find -print0` emits literal bytes and is portable\n\t// (GNU + busybox); the NUL delimiter also survives names containing newlines.\n\t// No TTY: a TTY's onlcr would rewrite every \\n in the stream to \\r\\n —\n\t// including a \\n that is part of a filename — corrupting the name. Without a\n\t// TTY the exec stream is multiplexed and demuxed below.\n\tcreateResp, err := dc.ContainerExecCreate(ctx, containerID, client.ExecCreateOptions{\n\t\tCmd:          []string{\"find\", dirPath, \"-maxdepth\", \"1\", \"-mindepth\", \"1\", \"!\", \"-name\", \".*\", \"-print0\"},\n\t\tAttachStdout: true,\n\t\tAttachStderr: true,\n\t})\n\tif err != nil {\n\t\treturn ContainerDirListing{}, fmt.Errorf(\"failed to create list exec for '%s': %w\", dirPath, err)\n\t}\n\n\tresp, err := dc.ContainerExecAttach(ctx, createResp.ID, client.ExecAttachOptions{})\n\tif err != nil {\n\t\treturn ContainerDirListing{}, fmt.Errorf(\"failed to attach list exec for '%s': %w\", dirPath, err)\n\t}\n\toutput, readErr := demuxExecStdout(resp.Reader, maxListStdoutBytes)\n\tresp.Close()\n\tif readErr != nil {\n\t\treturn ContainerDirListing{}, fmt.Errorf(\"failed to read list output for '%s': %w\", dirPath, readErr)\n\t}\n\n\tinspect, err := dc.ContainerExecInspect(ctx, createResp.ID)\n\tif err != nil {\n\t\treturn ContainerDirListing{}, fmt.Errorf(\"failed to inspect list exec for '%s': %w\", dirPath, err)\n\t}\n\tif inspect.ExitCode != 0 {\n\t\treturn ContainerDirListing{}, fmt.Errorf(\"list command failed for '%s' with exit code %d: %s\", dirPath, inspect.ExitCode, string(output))","sourceCodeStart":975,"sourceCodeEnd":1011,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/docker/client.go#L975-L1011","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)"],"exampleFix":"// before: exec fails because container is stopped\nlisting, err := dc.ListContainerDir(ctx, deadContainerID, \"/work\")\n// after: guard on container state before listing\nstate, _ := dc.ContainerInspect(ctx, containerID)\nif !state.State.Running {\n    return fmt.Errorf(\"container %s not running\", containerID)\n}\nlisting, err := dc.ListContainerDir(ctx, containerID, \"/work\")","handlingStrategy":"retry","validationCode":"state, err := dc.ContainerInspect(ctx, containerID)\nif err != nil || !state.State.Running {\n    return fmt.Errorf(\"container %s not listable\", containerID)\n}","typeGuard":null,"tryCatchPattern":"listing, err := client.ListContainerDir(ctx, containerID, dir)\nif err != nil {\n    var derr *dockerUnknownContainer\n    if errors.As(err, &derr) { /* container gone — recreate */ }\n    return err\n}","preventionTips":["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"],"tags":["docker","exec","container-lifecycle"],"backgroundTag":"docker-exec-create-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}