Skip to content

fix(frontend): don't retry project README fetch on 404/403#578

Open
mvanhorn wants to merge 1 commit into
calkit:mainfrom
mvanhorn:osc/572-readme-no-retry-on-404
Open

fix(frontend): don't retry project README fetch on 404/403#578
mvanhorn wants to merge 1 commit into
calkit:mainfrom
mvanhorn:osc/572-readme-no-retry-on-404

Conversation

@mvanhorn
Copy link
Copy Markdown

Closes #572.

Summary

useProjectReadme (in frontend/src/hooks/useProject.ts) used React Query's default retry policy, so fetching README.md from a project that has none caused 4 round-trips before the UI settled on "no README". A missing README is the common case for fresh projects, so the retries were pure latency with zero chance of succeeding.

Change

Adds the same retry predicate already used by useProject a few lines above — drop on Not Found / Forbidden, otherwise retry up to 3 times:

retry: (failureCount, error) => {
  if (error.message === "Not Found" || error.message === "Forbidden") {
    return false
  }
  return failureCount < 3
},

Plus a short comment explaining why missing README is the expected case.

Verification

  • tsc --noEmit clean (no new diagnostics in useProject.ts or anywhere else).
  • Same shape as the existing useProject retry predicate at useProject.ts:16-21, so behavior stays consistent between the two hooks.
  • Same shape as routes/_layout/$accountName/index.tsx:158-164 which also special-cases 404.

Frontend only. No backend changes.

Closes calkit#572.

`useProjectReadme` relied on React Query's default retry policy (3
attempts), so fetching `README.md` from a project that has none
burned four round-trips before settling on "no README". A missing
README is the common case for fresh projects, so the retries are pure
latency with no chance of success.

Adopts the same retry policy already used by `useProject` above it
(lines 16-21): drop retries on "Not Found" and "Forbidden", otherwise
fall back to up to three attempts for transient errors.

Pattern is already in the codebase, so this keeps the retry behaviour
consistent across the two hooks.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the frontend’s useProjectReadme hook to avoid React Query retries when a project’s README.md fetch fails with expected 404/403 responses, reducing unnecessary latency for new projects without a README.

Changes:

  • Add a React Query retry predicate to useProjectReadme to stop retrying on “Not Found” / “Forbidden”.
  • Add an inline comment explaining why missing READMEs are expected and shouldn’t trigger retries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +76 to +82
retry: (failureCount, error) => {
// A missing README is the common case for fresh projects — don't
// burn three extra round-trips before the UI settles on "no README".
if (error.message === "Not Found" || error.message === "Forbidden") {
return false
}
return failureCount < 3
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The retry predicate relies on matching error.message strings ("Not Found"/"Forbidden"). Since ProjectsService errors are ApiError with a stable numeric status, it would be more robust to branch on error.status === 404/403 (or to derive status with optional chaining) rather than on the message text. This also mirrors the status-based checks used elsewhere in the frontend and avoids breakage if the error mapping/message ever changes.

Copilot uses AI. Check for mistakes.
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.

Handle 404s properly from missing project READMEs

2 participants