{"record":{"id":"b09bcb2bb456d06d","repo":"vxcontrol/pentagi","slug":"failed-to-attach-file-check-exec-w","errorCode":null,"errorMessage":"failed to attach file-check exec: %w","messagePattern":"failed to attach file-check exec: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/tools.go","lineNumber":667,"sourceCode":"\tcmd = append(cmd, \"sh\", \"-c\",\n\t\t`for f in \"$@\"; do [ -f \"$f\" ] || printf '%s\\n' \"$f\"; done`, \"--\")\n\tfor _, e := range entries {\n\t\tcmd = append(cmd, e.containerPath)\n\t}\n\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}","sourceCodeStart":649,"sourceCodeEnd":685,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/tools.go#L649-L685","documentation":"This error wraps a failure from Docker's ContainerExecAttach call when the flowToolsExecutor tries to attach to a created exec instance inside the sandbox container to run a file-check command. It is thrown because, although the exec instance was created successfully, the streaming HTTP hijack (attach) to that instance failed. The wrapped error carries the underlying Docker client/daemon cause.","triggerScenarios":"fte.docker.ContainerExecAttach(ctx, createResp.ID, client.ExecAttachOptions{}) fails: container stopped/removed between create and attach, Docker daemon unreachable or restarting, context canceled, or the exec ID is invalid.","commonSituations":"Agent tool executes file checks while the target sandbox container is being torn down mid-flow; Docker daemon restarts under load; network interruption between the API server and dockerd (DOCKER_HOST socket/HTTP); flow context canceled when the user aborts the flow while a check is in flight.","solutions":["Check that the target container is running (docker ps) at the moment of the exec; recreate or restart the flow's sandbox container","Verify the Docker daemon is reachable: docker info from the backend container; check DOCKER_HOST and socket mount","Inspect wrapped error in logs: if 'context canceled', the flow/HTTP request was aborted — handle cancellation instead of retrying","Add retry with backoff for transient attach failures, or check container state before attaching"],"exampleFix":"// before\nresp, err := fte.docker.ContainerExecAttach(ctx, createResp.ID, client.ExecAttachOptions{})\nif err != nil {\n\treturn nil, fmt.Errorf(\"failed to attach file-check exec: %w\", err)\n}\n// after\nif err := ctx.Err(); err != nil {\n\treturn nil, fmt.Errorf(\"file-check canceled before attach: %w\", err)\n}\nresp, err := fte.docker.ContainerExecAttach(ctx, createResp.ID, client.ExecAttachOptions{})\nif err != nil {\n\treturn nil, fmt.Errorf(\"failed to attach file-check exec: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// before creating the exec\ninfo, err := cli.ContainerInspect(ctx, containerID)\nif err != nil || !info.State.Running {\n\treturn fmt.Errorf(\"container %s not running: %v\", containerID, err)\n}\nif err := ctx.Err(); err != nil {\n\treturn err\n}","typeGuard":null,"tryCatchPattern":"var ae *dockererr // inspect wrapped cause\nerr := runFileCheck(ctx)\nif err != nil {\n\tif errors.Is(err, context.Canceled) {\n\t\t// do not retry: caller aborted\n\t\treturn err\n\t}\n\tif strings.Contains(err.Error(), \"failed to attach\") {\n\t\t// transient: retry with backoff\n\t\terr = retry.Do(func() error { return runFileCheck(ctx) }, retry.Attempts(2))\n\t}\n}","preventionTips":["Check container state is running before creating/attaching execs","Keep DOCKER_HOST/socket connectivity verified in health checks","Avoid aborting flows mid-exec; propagate cancellation cleanly","Add bounded retries around transient Docker API calls"],"tags":["docker","exec","network","container"],"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"}