{"record":{"id":"80fcdaf9731929e1","repo":"glanceapp/glance","slug":"w-could-not-fetch-list-of-post-ids","errorCode":null,"errorMessage":"%w: could not fetch list of post IDs","messagePattern":"%w: could not fetch list of post IDs","errorType":"exception","errorClass":"errNoContent","httpStatus":null,"severity":"error","filePath":"internal/glance/widget-hacker-news.go","lineNumber":82,"sourceCode":"\nfunc (widget *hackerNewsWidget) Render() template.HTML {\n\treturn widget.renderTemplate(widget, forumPostsTemplate)\n}\n\ntype hackerNewsPostResponseJson struct {\n\tId           int    `json:\"id\"`\n\tScore        int    `json:\"score\"`\n\tTitle        string `json:\"title\"`\n\tTargetUrl    string `json:\"url,omitempty\"`\n\tCommentCount int    `json:\"descendants\"`\n\tTimePosted   int64  `json:\"time\"`\n}\n\nfunc fetchHackerNewsPostIds(sort string) ([]int, error) {\n\trequest, _ := http.NewRequest(\"GET\", fmt.Sprintf(\"https://hacker-news.firebaseio.com/v0/%sstories.json\", sort), nil)\n\tresponse, err := decodeJsonFromRequest[[]int](defaultHTTPClient, request)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: could not fetch list of post IDs\", errNoContent)\n\t}\n\n\treturn response, nil\n}\n\nfunc fetchHackerNewsPostsFromIds(postIds []int, commentsUrlTemplate string) (forumPostList, error) {\n\trequests := make([]*http.Request, len(postIds))\n\n\tfor i, id := range postIds {\n\t\trequest, _ := http.NewRequest(\"GET\", fmt.Sprintf(\"https://hacker-news.firebaseio.com/v0/item/%d.json\", id), nil)\n\t\trequests[i] = request\n\t}\n\n\ttask := decodeJsonFromRequestTask[hackerNewsPostResponseJson](defaultHTTPClient)\n\tjob := newJob(task, requests).withWorkers(30)\n\tresults, errs, err := workerPoolDo(job)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-hacker-news.go#L64-L100","documentation":"The request to the Hacker News Firebase API (https://hacker-news.firebaseio.com/v0/<sort>stories.json) failed during request execution or JSON decode, and is wrapped with errNoContent so the widget renders an empty list. The underlying decodeJsonFromRequest error (network, non-200, or bad JSON) is discarded from the message.","triggerScenarios":"Firebase API unreachable, rate-limiting, returning non-200, or network egress blocked from the glance host.","commonSituations":"Self-hosted glance in a container without internet egress; DNS failure for firebaseio.com; transient Firebase API outage; corporate proxy blocking the request.","solutions":["Verify connectivity: curl https://hacker-news.firebaseio.com/v0/topstories.json","Fix container DNS/egress (network policy, proxy env vars)","If Firebase is temporarily down, wait and let the widget's next update cycle retry"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"ids, err := fetchHackerNewsPostIds(sort)\nif err != nil {\n    if errors.Is(err, errNoContent) {\n        // transient third-party failure: keep previous cycle's posts\n        return widget.lastGoodPosts, nil\n    }\n    return nil, err\n}","preventionTips":["Ensure container egress to *.firebaseio.com before enabling the widget","Rely on the widget cache duration instead of tiny values, so API hiccups don't blank the panel"],"tags":["hacker-news","network","api","third-party"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}