{"record":{"id":"88e2c45b163f840f","repo":"glanceapp/glance","slug":"checking-session-id-v","errorCode":null,"errorMessage":"checking session ID: %v","messagePattern":"checking session ID: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-dns-stats.go","lineNumber":441,"sourceCode":"\tfetchNewSessionID := func() error {\n\t\tnewSessionID, err := fetchPiholeSessionID(instanceURL, client, password)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsessionID = newSessionID\n\t\treturn nil\n\t}\n\n\tif sessionID == \"\" {\n\t\tif err := fetchNewSessionID(); err != nil {\n\t\t\tslog.Error(\"Failed to fetch Pihole v6 session ID\", \"error\", err)\n\t\t\treturn nil, \"\", fmt.Errorf(\"fetching session ID: %v\", err)\n\t\t}\n\t} else {\n\t\tisValid, err := checkPiholeSessionIDIsValid(instanceURL, client, sessionID)\n\t\tif err != nil {\n\t\t\tslog.Error(\"Failed to check Pihole v6 session ID validity\", \"error\", err)\n\t\t\treturn nil, \"\", fmt.Errorf(\"checking session ID: %v\", err)\n\t\t}\n\n\t\tif !isValid {\n\t\t\tif err := fetchNewSessionID(); err != nil {\n\t\t\t\tslog.Error(\"Failed to renew Pihole v6 session ID\", \"error\", err)\n\t\t\t\treturn nil, \"\", fmt.Errorf(\"renewing session ID: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tvar wg sync.WaitGroup\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\ttype statsResponseJson struct {\n\t\tQueries struct {\n\t\t\tTotal          int     `json:\"total\"`\n\t\t\tBlocked        int     `json:\"blocked\"`","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-dns-stats.go#L423-L459","documentation":"Returned by the Pi-hole v6 stats fetcher when a previously cached session ID exists but checkPiholeSessionIDIsValid (GET /api/auth with the SID) itself errored — i.e. the validity check could not be performed due to a transport or decoding failure, as opposed to the session simply being expired (which would silently renew instead).","triggerScenarios":"GET {url}/api/auth with the stored SID fails at the HTTP layer: connection refused mid-run, DNS failure, TLS handshake error, timeout, or a response body that cannot be processed.","commonSituations":"Pi-hole restarted or became unreachable between the initial auth and the stats fetch; flaky link; reverse proxy briefly returning 502 pages; the SID cache outliving a Pi-hole restart.","solutions":["Check Pi-hole is up and reachable from the glance host when the error occurs.","If it recurs after every Pi-hole restart, the cached SID becomes invalid — a restart of glance (or waiting for cache expiry) forces a fresh fetch.","Stabilize the reverse proxy/network path if intermittent 502s are the cause."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"stats, sid, err := fetchPiholeV6Stats(...)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"checking session ID\") {\n        // transport-level failure of the validity check: retry on next refresh,\n        // do not wipe the cached SID (it may still be valid)\n    }\n}","preventionTips":["Keep the Pi-hole host monitored so reachability issues are visible independently.","Treat validity-check errors as transient; avoid purging session state on them.","Ensure proxies between glance and Pi-hole have sane timeouts."],"tags":["network","pihole","session","dns-stats","widget"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}