{"record":{"id":"982314201be897a0","repo":"wtfutil/wtf","slug":"could-not-get-docker-system-info-w","errorCode":null,"errorMessage":"could not get docker system info: %w","messagePattern":"could not get docker system info: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/docker/client.go","lineNumber":17,"sourceCode":"package docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/dustin/go-humanize\"\n)\n\nfunc (widget *Widget) getSystemInfo() string {\n\tinfo, err := widget.cli.Info(context.Background())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not get docker system info: %w\", err).Error()\n\t}\n\n\tdiskUsage, err := widget.cli.DiskUsage(context.Background(), types.DiskUsageOptions{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not get disk usage: %w\", err).Error()\n\t}\n\n\tvar duContainer int64\n\tfor _, c := range diskUsage.Containers {\n\t\tduContainer += c.SizeRw\n\t}\n\tvar duImg int64\n\tfor _, im := range diskUsage.Images {\n\t\tduImg += im.Size\n\t}\n\tvar duVol int64\n\tfor _, v := range diskUsage.Volumes {\n\t\tduVol += v.UsageData.Size","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/docker/client.go#L1-L35","documentation":"The docker widget's getSystemInfo calls cli.Info(ctx); if the Docker daemon request fails, the error is stringified via fmt.Errorf(...).Error() into the widget's display buffer. This means the widget cannot talk to the Docker daemon's /info endpoint. Note the code converts an error to a string and returns it as display text rather than propagating it.","triggerScenarios":"cli.Info fails: Docker daemon not running, DOCKER_HOST points to an unreachable host, permission denied on /var/run/docker.sock, or the daemon restarts mid-session.","commonSituations":"Docker Desktop not started, user not in the docker group, remote DOCKER_HOST with a dead tunnel, or snap/docker rootless installs with different socket paths.","solutions":["Verify the daemon is up: docker info in the same environment/terminal.","Check DOCKER_HOST and DOCKER_CONTEXT env vars match the intended daemon.","Fix socket permissions: add your user to the docker group or use sudo/rootless setup correctly.","Restart Docker Desktop / systemctl restart docker if the daemon stalled."],"exampleFix":"// before\ninfo, err := widget.cli.Info(context.Background())\nif err != nil {\n\treturn fmt.Errorf(\"could not get docker system info: %w\", err).Error()\n}\n// after\ninfo, err := widget.cli.Info(context.Background())\nif err != nil {\n\treturn fmt.Errorf(\"could not get docker system info: %w\", err).Error() // surface DOCKER_HOST & ping daemon in setup docs\n}","handlingStrategy":"fallback","validationCode":"if _, err := net.Dial(\"unix\", \"/var/run/docker.sock\"); err != nil {\n\t// daemon socket unreachable — show setup hint instead of calling Info\n}","typeGuard":"func isDaemonUnreachable(err error) bool {\n\treturn errors.Is(err, syscall.ECONNREFUSED) || errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.EACCES)\n}","tryCatchPattern":"info, err := widget.cli.Info(ctx)\nif err != nil {\n\twidget.displayBuffer = fmt.Sprintf(\"docker unavailable: %v — check 'docker info'\", err)\n\treturn // degrade gracefully, retry on next refresh tick\n}","preventionTips":["Confirm docker info works in the same user session before running the widget.","Add your user to the docker group or configure rootless docker correctly.","Keep DOCKER_HOST consistent between your shell and the app's environment."],"tags":["docker","daemon","network","go"],"backgroundTag":"docker-daemon-unreachable","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}