{"record":{"id":"d3dfb0381cb991ca","repo":"vxcontrol/pentagi","slug":"failed-to-read-file-check-output-w","errorCode":null,"errorMessage":"failed to read file-check output: %w","messagePattern":"failed to read file-check output: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/tools.go","lineNumber":672,"sourceCode":"\n\tcontainerName := PrimaryTerminalName(fte.cfg.TenantPrefix(), fte.flowID)\n\tcreateResp, err := fte.docker.ContainerExecCreate(ctx, containerName, client.ExecCreateOptions{\n\t\tCmd:          cmd,\n\t\tAttachStdout: true,\n\t\tAttachStderr: true,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create file-check exec: %w\", err)\n\t}\n\n\tresp, err := fte.docker.ContainerExecAttach(ctx, createResp.ID, client.ExecAttachOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to attach file-check exec: %w\", err)\n\t}\n\toutput, readErr := io.ReadAll(resp.Reader)\n\tresp.Close()\n\tif readErr != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read file-check output: %w\", readErr)\n\t}\n\tinspect, err := fte.docker.ContainerExecInspect(ctx, createResp.ID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to inspect file-check exec: %w\", err)\n\t}\n\tif inspect.ExitCode != 0 {\n\t\treturn nil, fmt.Errorf(\"file-check exec failed with exit code %d: %s\", inspect.ExitCode, strings.TrimSpace(string(output)))\n\t}\n\n\tbyContainerPath := make(map[string]fileSyncEntry, len(entries))\n\tfor _, e := range entries {\n\t\tbyContainerPath[e.containerPath] = e\n\t}\n\n\tvar missing []fileSyncEntry\n\tfor _, line := range strings.Split(string(output), \"\\n\") {\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" {","sourceCodeStart":654,"sourceCodeEnd":690,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/tools.go#L654-L690","documentation":"This error wraps a failure from io.ReadAll(resp.Reader) after successfully attaching to a Docker exec instance. The exec attach stream was opened but reading the combined stdout/stderr stream failed, typically because the connection was cut mid-read or the daemon closed it abnormally. resp.Close() is still called before returning, so no fd leak occurs.","triggerScenarios":"io.ReadAll(resp.Reader) returns an error: the hijacked connection to dockerd drops during command execution, the daemon restarts while the exec command is running, or the stream is aborted (e.g. container removed or OOM-killed mid-run).","commonSituations":"Long-running or high-output file-check commands inside a sandboxed container when the Docker daemon or network is unstable; container killed by resource limits while producing output; proxy/load balancer in front of remote DOCKER_HOST timing out the hijacked stream.","solutions":["Check the wrapped readErr: 'unexpected EOF' or 'connection reset' indicates a dropped hijacked connection — verify daemon/network stability","Confirm the sandbox container was not killed mid-run (docker inspect <container> --format '{{.State.OOMKilled}} {{.State.Status}}')","Reduce output volume of the file-check command or stream/consume output incrementally with bounds instead of ReadAll","Retry the whole file-check exec once on transient stream errors"],"exampleFix":"// before\noutput, readErr := io.ReadAll(resp.Reader)\nresp.Close()\nif readErr != nil {\n\treturn nil, fmt.Errorf(\"failed to read file-check output: %w\", readErr)\n}\n// after\noutput, readErr := io.ReadAll(io.LimitReader(resp.Reader, maxCheckOutputBytes))\nresp.Close()\nif readErr != nil {\n\treturn nil, fmt.Errorf(\"failed to read file-check output: %w\", readErr)\n}","handlingStrategy":"try-catch","validationCode":"// ensure the container and daemon connection are healthy before running the check\ninfo, err := cli.ContainerInspect(ctx, containerID)\nif err != nil || !info.State.Running {\n\treturn fmt.Errorf(\"container not available for file-check: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"err := runFileCheck(ctx)\nvar transient bool\nif err != nil && strings.Contains(err.Error(), \"failed to read file-check output\") {\n\ttransient = true // hijacked stream dropped; safe to retry the whole exec once\n}\nif transient {\n\terr = runFileCheck(ctx)\n}","preventionTips":["Bound command output size instead of unbounded io.ReadAll","Avoid killing/removing the sandbox container while checks run","Monitor Docker daemon restarts; treat 'unexpected EOF' as daemon/network instability","Set conservative timeouts on remote DOCKER_HOST proxies for hijacked streams"],"tags":["docker","io","stream","container"],"backgroundTag":"docker-exec-stream-read-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}