{"record":{"id":"4bc5365867da624d","repo":"vxcontrol/pentagi","slug":"container-runtime-check-failed-w","errorCode":null,"errorMessage":"container runtime check failed: %w","messagePattern":"container runtime check failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/terminal.go","lineNumber":455,"sourceCode":"\tsuccessMsg := fmt.Sprintf(\"File successfully saved to %s\", path)\n\tstyledMsg := fmt.Sprintf(\"%s%s%s%s\", ansiColorSystemMsg, successMsg, ansiColorReset, ansiLineTerminator)\n\t_, err := t.tlp.PutMsg(ctx, database.TermlogTypeStdin, styledMsg, t.containerID, t.taskID, t.subtaskID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to put terminal log (write file cmd): %w\", err)\n\t}\n\n\treturn fmt.Sprintf(\"Successfully wrote %d bytes to %s\", len(content), path), nil\n}\n\n// writeFileToContainer copies content into the flow's container at path,\n// overwriting it. It performs no terminal-log writes; WriteFile and EditFile\n// each log their own, differently-worded, success message.\nfunc (t *terminal) writeFileToContainer(ctx context.Context, flowID int64, path, content string) error {\n\tcontainerName := PrimaryTerminalName(t.tenantPrefix, flowID)\n\n\tisRunning, err := t.dockerClient.IsContainerRunning(ctx, t.containerLID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"container runtime check failed: %w\", err)\n\t}\n\tif !isRunning {\n\t\treturn fmt.Errorf(\"target container is not operational\")\n\t}\n\n\t// Docker SDK requires TAR format for file transfer\n\ttarBuffer := &bytes.Buffer{}\n\tarchiveWriter := tar.NewWriter(tarBuffer)\n\tdefer archiveWriter.Close()\n\n\tfilename := filepath.Base(path)\n\tfileDescriptor := &tar.Header{\n\t\tName: filename,\n\t\tMode: 0600,\n\t\tSize: int64(len(content)),\n\t}\n\terr = archiveWriter.WriteHeader(fileDescriptor)\n\tif err != nil {","sourceCodeStart":437,"sourceCodeEnd":473,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/terminal.go#L437-L473","documentation":"writeFileToContainer begins by calling dockerClient.IsContainerRunning(ctx, t.containerLID) as a preconditions check. If that Docker API call itself returns an error (as opposed to reporting not-running), the error is wrapped with this message. This is a daemon/transport-level failure — the platform could not even ask Docker about the container.","triggerScenarios":"Docker daemon unreachable (socket permission denied, daemon restarting, /var/run/docker.sock not mounted), Docker API timeout, the containerLID no longer resolves to a live container object returning a 404, or a remote DOCKER_HOST connection dropped.","commonSituations":"Deploying without the Docker socket mounted into the backend container; `dockerd` crash/restart mid-flow; DOCKER_HOST over TCP with network/TLS misconfig; container was force-removed (`docker rm -f`) while the flow still holds its ID.","solutions":["Verify Docker access from the backend: `docker info` inside the backend container / check the socket mount and group permissions (998:998 or :/var/run/docker.sock)","Read the wrapped cause: 404 means the container was removed (recreate the flow's container); connection refused means the daemon is down (restart dockerd)","If remote, check DOCKER_HOST connectivity and TLS certs; retry with backoff for transient daemon restarts","Ensure the platform recreates the terminal container if the lifecycle manager removed it"],"exampleFix":"// before\nisRunning, err := t.dockerClient.IsContainerRunning(ctx, t.containerLID)\nif err != nil {\n    return fmt.Errorf(\"container runtime check failed: %w\", err)\n}\n// after (caller-side retry)\nvar lastErr error\nfor i := 0; i < 3; i++ {\n    running, err := dockerClient.IsContainerRunning(ctx, containerLID)\n    if err == nil {\n        break // proceed with `running`\n    }\n    lastErr = err\n    time.Sleep(time.Duration(1<<i) * time.Second)\n}\nif lastErr != nil {\n    return fmt.Errorf(\"container runtime check failed after retries: %w\", lastErr)\n}","handlingStrategy":"retry","validationCode":"if _, err := dockerClient.Ping(ctx); err != nil {\n    return fmt.Errorf(\"docker daemon unreachable, check socket/DOCKER_HOST: %w\", err)\n}","typeGuard":"func isDaemonUnavailable(err error) bool {\n    return errors.Is(err, syscall.ECONNREFUSED) || errors.Is(err, syscall.ENOENT) || errors.Is(err, context.DeadlineExceeded)\n}","tryCatchPattern":"_, err := tool.WriteFile(ctx, flowID, content, path)\nif err != nil && strings.Contains(err.Error(), \"container runtime check failed\") {\n    // check dockerd, socket mount, or DOCKER_HOST, then retry with backoff\n    return fmt.Errorf(\"docker unavailable: %w\", err)\n}","preventionTips":["Mount /var/run/docker.sock (or configure DOCKER_HOST) into the backend and verify at startup","Health-check the Docker daemon before starting flows","Retry IsContainerRunning with exponential backoff for transient daemon restarts","Alert on 404s for known container IDs — the container was removed out-of-band"],"tags":["docker","daemon","connectivity"],"backgroundTag":"docker-daemon-unreachable","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}