Skip to content

fix(github): render GitHub Enterprise PR avatars via API avatar_url - #9107

Merged
nwparker merged 3 commits into
mainfrom
nwparker/fix-8784-wave4
Jul 17, 2026
Merged

nwparker merged 3 commits into
mainfrom
nwparker/fix-8784-wave4

Conversation

@nwparker

Copy link
Copy Markdown
Contributor

Description

Fixes #8784.

On GitHub Enterprise, PR author / reviewer / assignee avatars rendered blank. Orca built the avatar URL from the login (https://github.com/{login}.png), which 404s for Enterprise users because their login doesn't exist on github.com. The API already returns a fully-formed avatar_url, so the fix is to use it.

Takes over / supersedes #8831 by @davkim1030 — core approach and commits credited to them; rebased onto current main with small hardenings and the #8784 regression kit.

What changed:

  • Carry the API avatar_url through the work-item mappers (authorAvatarUrl on GitHubWorkItem) and stamp author/reviewer/assignee avatars onto the PR detail item using the same GraphQL user(login:) batch that already resolves comment avatars. No extra round-trip — the mention-author batch now also covers the item's reviewers/assignees, and the resolved avatars are reused to enrich the item.
  • Shared GitHubUserAvatar component for all PR author/reviewer/assignee avatars: prefers the API avatar_url, falls back to the login URL (so github.com behavior is unchanged), and degrades to an initials placeholder on image load error.
  • Fixed a placeholder latch bug: the component tracked failure as a boolean, so a row that 404'd on the early login-based URL (before enrichment landed) stayed blank forever. It now tracks the failed src, so a row recovers once the real avatar_url arrives after first paint.
  • Hardenings on top of fix(github): render GitHub Enterprise PR avatars via API avatar_url #8831: resolveGitHubUserAvatarSrc treats whitespace-only avatarUrl as empty and skips empty login so we never request github.com/.png; [Bug]: GitHub Enterprise — PR author avatars fail to load (built from login instead of avatar_url) #8784 repro converted to a regression source-guard.

No host-specific logic is introduced; github.com is unaffected.

Evidence

pnpm exec vitest run --config config/vitest.config.ts \
  src/renderer/src/components/github/github-user-avatar.test.tsx \
  src/renderer/src/components/github/repro-8784-ghe-avatar-fallback.test.ts \
  src/main/github/work-item-details.test.ts
# → 24 tests passed
pnpm exec oxlint <touched files>  # 0 errors
pnpm exec tsc --noEmit -p config/tsconfig.node.json
pnpm exec tsc --noEmit -p config/tsconfig.tc.web.json
  • github-user-avatar.test.tsx — prefers API avatar_url, login fallback, initials on error, non-BMP initials, retries when avatarUrl changes after an earlier src failed, empty-src initials.
  • repro-8784-ghe-avatar-fallback.test.ts — regression guards that author/reviewer paths use GitHubUserAvatar + authorAvatarUrl (no hardcoded login.png in TaskPage / author chip).
  • work-item-details.test.ts — GraphQL enrichment stamps author/reviewer/assignee avatars (including overriding u/0 placeholders and non-participating issue assignees).

Manual GHE verification was done in #8831 (author, requested reviewers, approved reviewers, assignees).

ELI5

Enterprise users don't have profiles on public github.com, so building avatars as github.com/username.png shows a broken image. The Enterprise API already gives a real avatar link; we now use that link, and if the picture still fails we show initials instead of a blank hole. When the real link arrives a moment later, the picture appears.

User-regression-tradeoffs

Area Risk Mitigation
github.com avatars Low — login.png fallback kept when API omits avatar Prefer API URL when present; same fallback as before
GHE list chips without avatar_url Medium — one failed github.com request then initials Detail enrichment stamps real URLs; onError → initials (better than permanent blank)
Rate limit / GraphQL batch Low — reuses existing mention-author batch Display users ordered first so 40-login cap doesn't drop reviewers
Tasks list avatars Out of scope — gh pr list often omits avatars Follow-up; detail view is the reported bug
Security Low — only API-provided URL into <img src> No new IPC; GraphQL stays main-process

Tradeoff accepted: without host detection we still briefly try login.png on GHE when enrichment hasn't arrived; failed-src tracking + initials avoids a permanent broken image, and enrichment replaces the src after first paint.

Credit: approach and primary implementation from #8831 (@davkim1030).

davkim1030 and others added 3 commits July 16, 2026 17:38
Fixes #8784.

GitHub Enterprise user logins don't exist on github.com, so the
`https://github.com/{login}.png` URL that PR author/reviewer/assignee
avatars were built from returned 404 and rendered blank.

- Carry the API-provided `avatar_url` through the work-item mappers
  (`authorAvatarUrl`) and stamp author/reviewer/assignee avatars onto the
  PR detail item using the same GraphQL `user(login:)` batch that already
  resolves comment avatars — no extra round-trip (the mention-author batch
  now also covers the item's reviewers/assignees).
- Route all PR author/reviewer/assignee avatars through a shared
  `GitHubUserAvatar` component that prefers the API avatar_url, falls back
  to the login URL (github.com behavior unchanged), and degrades to an
  initials placeholder on load error.
- Fix the placeholder latch: the component now tracks the failed src
  rather than a boolean, so a row that 404s on the early login-based URL
  recovers once the enriched avatar_url arrives after first paint. This was
  why author/requested-reviewer avatars stayed blank while late-mounted
  assignee/approved-reviewer avatars rendered.

No host-specific logic; github.com is unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…names

Address CodeRabbit review on #8831:
- Pull avatarUrl/name in the GraphQL assignees connection so a
  non-participating assignee (common on GitHub Enterprise) no longer
  renders a blank avatar.
- Build initials by code point and skip symbol-only words so a display
  name that leads with an emoji yields clean letters, not a broken
  surrogate half.
- Convert avatar-helper why-comments to TSDoc for docstring coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Export resolveGitHubUserAvatarSrc so empty/whitespace avatarUrl and empty
login never build a bogus github.com/.png request. Convert the #8784 repro
into a source-guard regression and cover empty-src initials.

Based on #8831 by @davkim1030 (avatar_url enrichment + GitHubUserAvatar).
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@nwparker, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 31430f22-e689-4cd8-a299-dd449c2e6cc0

📥 Commits

Reviewing files that changed from the base of the PR and between 1cdc8e8 and 2e606a8.

📒 Files selected for processing (10)
  • src/main/github/client.ts
  • src/main/github/work-item-details.test.ts
  • src/main/github/work-item-details.ts
  • src/renderer/src/components/GitHubItemDialog.tsx
  • src/renderer/src/components/PullRequestPage.tsx
  • src/renderer/src/components/TaskPage.tsx
  • src/renderer/src/components/github/github-user-avatar.test.tsx
  • src/renderer/src/components/github/github-user-avatar.tsx
  • src/renderer/src/components/github/repro-8784-ghe-avatar-fallback.test.ts
  • src/shared/types.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nwparker
nwparker merged commit 539e060 into main Jul 17, 2026
2 checks passed
@nwparker
nwparker deleted the nwparker/fix-8784-wave4 branch July 17, 2026 02:24
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
…tablyai#9107)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: davkim1030 <davkim1030@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: GitHub Enterprise — PR author avatars fail to load (built from login instead of avatar_url)

2 participants