{"record":{"id":"9333bad0af7aee27","repo":"Billionmail/BillionMail","slug":"failed-waiting-for-container-execution-w","errorCode":null,"errorMessage":"failed waiting for container execution: %w","messagePattern":"failed waiting for container execution: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/dockerapi/dockerapi.go","lineNumber":335,"sourceCode":"\t\t\"\",\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create temporary container: %w\", err)\n\t}\n\tcontainerID := resp.ID\n\tdefer d.cleanupContainer(ctx, containerID) // Ensure container is cleaned up\n\n\t// Start container\n\tif err := d.client.ContainerStart(ctx, containerID, container.StartOptions{}); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to start temporary container: %w\", err)\n\t}\n\n\t// Wait for container execution to complete\n\tstatusCh, errCh := d.client.ContainerWait(ctx, containerID, container.WaitConditionNotRunning)\n\tselect {\n\tcase err := <-errCh:\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed waiting for container execution: %w\", err)\n\t\t}\n\tcase status := <-statusCh:\n\t\tresult.ExitCode = int(status.StatusCode)\n\t}\n\n\t// Get container logs\n\toptions := container.LogsOptions{\n\t\tShowStdout: true,\n\t\tShowStderr: true,\n\t}\n\tlogs, err := d.client.ContainerLogs(ctx, containerID, options)\n\tif err != nil {\n\t\tresult.Error = fmt.Sprintf(\"failed to get command output: %v\", err)\n\t} else {\n\t\tdefer logs.Close()\n\t\tvar buf bytes.Buffer\n\t\t_, err := io.Copy(&buf, logs)\n\t\tif err != nil {","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/dockerapi/dockerapi.go#L317-L353","documentation":"ExecHostCommand registers ContainerWait with WaitConditionNotRunning and selects on the error channel; a non-nil error from the wait stream is wrapped as 'failed waiting for container execution'. This means the Docker API errored while streaming wait state — usually the container was removed, the daemon restarted, or the context was cancelled — not that the command exited non-zero (that is reported via result.ExitCode).","triggerScenarios":"Calling ExecHostCommand/ExecHostShellCommand (or addNewRules/deleteOldRules) when: the passed ctx is cancelled/times out during ContainerWait; the daemon drops the connection; the container is killed/removed externally while waiting; containerd reports a wait error.","commonSituations":"Long-running host commands exceeding an HTTP/request context deadline; Docker daemon restart mid-execution; someone running docker rm on the temp container; OOM killer terminating the container causing a wait-stream error on some daemon versions.","solutions":["Check the wrapped error for context.DeadlineExceeded/Canceled and extend or remove the ctx timeout for long commands","Ensure nothing else removes or manages these anonymous containers while they run (cleanupContainer is already deferred)","Verify daemon stability (uptime, journalctl -u docker) if the connection dropped mid-wait","Retry the command once transiently — the temp container is auto-cleaned so retry is safe"],"exampleFix":"// before\nstatusCh, errCh := d.client.ContainerWait(ctx, containerID, container.WaitConditionNotRunning)\n// after: use a detached context for waiting so HTTP client deadlines don't abort the stream\nstatusCh, errCh := d.client.ContainerWait(context.WithoutCancel(ctx), containerID, container.WaitConditionNotRunning)","handlingStrategy":"retry","validationCode":"// bound the work: avoid waiting on long commands with a short ctx\ncmdCtx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)\ndefer cancel()","typeGuard":null,"tryCatchPattern":"res, err := docker.ExecHostCommand(ctx, cmd)\nif err != nil {\n\tif errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {\n\t\t// timeout: reschedule or escalate\n\t} else if strings.Contains(err.Error(), \"failed waiting for container execution\") {\n\t\t// transient daemon/transport error: safe to retry, temp container auto-cleaned\n\t\tres, err = docker.ExecHostCommand(ctx, cmd)\n\t}\n}","preventionTips":["Pass a context with a generous timeout matching the expected command duration","Never docker rm/prune while ExecHostCommand containers may be running","Detect context cancellation errors distinctly from daemon errors","Retry once on wait-stream errors; the deferred cleanupContainer keeps state clean"],"tags":["docker","container-wait","context-cancelled"],"backgroundTag":"docker-container-wait-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}