{"record":{"id":"84c60062f2185ba6","repo":"vxcontrol/pentagi","slug":"failed-to-attach-to-exec-process-w","errorCode":null,"errorMessage":"failed to attach to exec process: %w","messagePattern":"failed to attach to exec process: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/terminal.go","lineNumber":273,"sourceCode":"\t\t\treturn fmt.Sprintf(\"Command started in background with timeout %s (still running)\", timeout), nil\n\t\t}\n\t}\n\n\treturn t.getExecResult(ctx, createResp.ID, timeout)\n}\n\nfunc (t *terminal) getExecResult(ctx context.Context, id string, timeout time.Duration) (string, error) {\n\tif timeout > 0 {\n\t\tvar cancel context.CancelFunc\n\t\tctx, cancel = context.WithTimeout(ctx, timeout)\n\t\tdefer cancel()\n\t}\n\n\tresp, err := t.dockerClient.ContainerExecAttach(ctx, id, client.ExecAttachOptions{\n\t\tTTY: true,\n\t})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to attach to exec process: %w\", err)\n\t}\n\tdefer resp.Close()\n\n\tdst := bytes.Buffer{}\n\terrChan := make(chan error, 1)\n\n\tgo func() {\n\t\t_, copyErr := io.Copy(&dst, resp.Reader)\n\t\terrChan <- copyErr\n\t}()\n\n\tselect {\n\tcase err := <-errChan:\n\t\tif err != nil && err != io.EOF {\n\t\t\treturn \"\", fmt.Errorf(\"failed to copy output: %w\", err)\n\t\t}\n\tcase <-ctx.Done():\n\t\t// Close the response to unblock io.Copy","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/terminal.go#L255-L291","documentation":"This error is returned by getExecResult when the Docker API call ContainerExecAttach fails, meaning the library could not attach a TTY stream to the already-created exec instance inside the container. Attaching is required to capture the command's output, so without it the result cannot be read.","triggerScenarios":"ExecCommand → getExecResult calls t.dockerClient.ContainerExecAttach(ctx, id, ExecAttachOptions{TTY:true}) and the Docker daemon returns an error: exec instance was removed, container stopped between create and attach, daemon connection lost, or the exec ID is invalid.","commonSituations":"Container stopped/restarted mid-command; Docker daemon outage or socket permission issues; race where the exec completes and is reaped before attach; Docker API version mismatches.","solutions":["Verify the target container is running before executing (docker ps / IsContainerRunning)","Check Docker daemon health and socket permissions (docker info; user in docker group)","Retry the command — attach races are often transient","Confirm the Docker client library and daemon API versions are compatible"],"exampleFix":"// before\nout, err := term.ExecCommand(ctx, flowID, cmd, false) // container was just restarted\n// after\nif ok, _ := docker.IsContainerRunning(ctx, containerLID); !ok {\n    return errors.New(\"container not running; start it before ExecCommand\")\n}\nout, err := term.ExecCommand(ctx, flowID, cmd, false)","handlingStrategy":"retry","validationCode":"if ok, err := docker.IsContainerRunning(ctx, containerLID); err != nil || !ok {\n    return fmt.Errorf(\"container not ready before exec: running=%v err=%v\", ok, err)\n}","typeGuard":null,"tryCatchPattern":"out, err := term.ExecCommand(ctx, flowID, cmd, false)\nif err != nil && strings.Contains(err.Error(), \"failed to attach to exec process\") {\n    time.Sleep(500 * time.Millisecond)\n    out, err = term.ExecCommand(ctx, flowID, cmd, false) // single retry\n}","preventionTips":["Confirm the container is running before issuing execs","Monitor Docker daemon health; attach failures often follow daemon drops","Keep Docker client API version aligned with the daemon","Avoid stopping/restarting the container while commands are in flight"],"tags":["docker","exec","attach","network"],"backgroundTag":"docker-exec-attach-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}