{"record":{"id":"a2e00c03786a9848","repo":"GoogleContainerTools/skaffold","slug":"creating-github-comment-w","errorCode":null,"errorMessage":"creating github comment: %w","messagePattern":"creating github comment: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/webhook/github/github.go","lineNumber":64,"sourceCode":"\n\t// Return a client instance from github\n\tclient := github.NewClient(tc)\n\treturn &Client{\n\t\tClient: client,\n\t\tctx:    context.Background(),\n\t}\n}\n\n// CommentOnPR comments message on the PR\nfunc (g *Client) CommentOnPR(pr *github.PullRequestEvent, message string) error {\n\tcomment := &github.IssueComment{\n\t\tBody: &message,\n\t}\n\n\tlog.Printf(\"Creating comment on PR %d: %s\", pr.PullRequest.GetNumber(), message)\n\t_, _, err := g.Client.Issues.CreateComment(g.ctx, constants.GithubOwner, constants.GithubRepo, pr.PullRequest.GetNumber(), comment)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating github comment: %w\", err)\n\t}\n\tlog.Printf(\"Successfully commented on PR %d.\", pr.GetNumber())\n\treturn nil\n}\n\n// RemoveLabelFromPR removes label from pr\nfunc (g *Client) RemoveLabelFromPR(pr *github.PullRequestEvent, label string) error {\n\t_, err := g.Client.Issues.RemoveLabelForIssue(g.ctx, constants.GithubOwner, constants.GithubRepo, pr.GetNumber(), label)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"deleting label: %w\", err)\n\t}\n\tlog.Printf(\"Successfully deleted label from PR %d\", pr.GetNumber())\n\treturn nil\n}\n","sourceCodeStart":46,"sourceCodeEnd":79,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/webhook/github/github.go#L46-L79","documentation":"Returned by Client.CommentOnPR in Skaffold's GitHub webhook when the GitHub API call Issues.CreateComment fails while posting a review comment on a pull request. The original GitHub client error is wrapped with %w so callers can unwrap and inspect the root cause (rate limits, auth, network).","triggerScenarios":"Calling CommentOnPR when the GitHub Issues API CreateComment request errors: invalid/expired token, missing repo write scope, wrong owner/repo constants, PR number no longer valid, or network failure.","commonSituations":"Webhook runs in CI with a GITHUB_TOKEN lacking `repo` or pull-request write scopes; token expired; hitting secondary rate limits from automated commenting; repository renamed/transferred so constants.GithubOwner/GithubRepo no longer match.","solutions":["Unwrap the error (`errors.Unwrap` / `errors.As`) and check the GitHub API status; fix auth if 401/403 or scopes if 404 on a private repo.","Regenerate/refresh the GitHub token and grant it repo write (or `pull-requests: write` for fine-grained tokens).","Verify constants.GithubOwner and constants.GithubRepo match the actual repository the PR belongs to.","If 403 with rate-limit headers, add backoff/retry honoring X-RateLimit-Reset.","Check network/proxy connectivity from the webhook host to api.github.com."],"exampleFix":"// before\nerr := g.CommentOnPR(pr, msg)\n// after\nif err := g.CommentOnPR(pr, msg); err != nil {\n    var ghErr *github.RateLimitError\n    if errors.As(err, &ghErr) {\n        time.Sleep(time.Until(ghErr.Rate.Reset.Time))\n        err = g.CommentOnPR(pr, msg)\n    }\n    if err != nil { log.Printf(\"comment failed: %v\", err) }\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight: verify token and repo access\nresp, err := http.Get(\"https://api.github.com/repos/\" + owner + \"/\" + repo)\n// 404 => bad repo or token lacks access; abort before commenting","typeGuard":null,"tryCatchPattern":"// Go\nif err := g.CommentOnPR(pr, msg); err != nil {\n    var rlErr *github.RateLimitError\n    var respErr *github.ErrorResponse\n    switch {\n    case errors.As(err, &rlErr):\n        time.Sleep(time.Until(rlErr.Rate.Reset.Time))\n    case errors.As(err, &respErr) && respErr.Response.StatusCode == 401:\n        // refresh token\n    default:\n        log.Printf(\"comment on PR failed: %v\", err)\n    }\n}","preventionTips":["Use a token with repo / pull-requests write scope and a non-expiring CI secret rotation policy.","Honor rate limits with backoff for automated PR commenting.","Keep owner/repo constants in sync with the actual repository."],"tags":["github","api","webhook","http"],"backgroundTag":"github-api-request-failed","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}