Skip to content

fix(proposal): show not-found when requested proposal ID doesn't exist#398

Merged
yhabib merged 1 commit into
mainfrom
fix/proposal-not-found-fallback
May 29, 2026
Merged

fix(proposal): show not-found when requested proposal ID doesn't exist#398
yhabib merged 1 commit into
mainfrom
fix/proposal-not-found-fallback

Conversation

@yhabib
Copy link
Copy Markdown
Collaborator

@yhabib yhabib commented May 29, 2026

Motivation

Landing on /voting/proposals/:id with an ID that doesn't exist (e.g. a manage-neuron proposal we don't surface) was rendering a different, neighboring proposal instead of a not-found state. The URL kept the requested ID but the content was for whichever existing proposal had ID ≤ the requested one. Easy repro: open https://dashboard.internetcomputer.org/proposal/141983 on the IC dashboard and click through to our app — you land on /voting/proposals/141983 and see an unrelated proposal.

Root cause: useGovernanceProposal calls listProposals with beforeProposal: proposalId + 1n, limit: 1. That's a range query, not a point lookup, so when the requested ID is missing the canister returns the next-lower existing proposal. The hook returned res.proposals[0] without checking that the ID matched.

Changes

  • Added a matchesRequestedId filter in useGovernanceProposal so a result whose ID doesn't match the requested one becomes undefined. Kept using list_proposals (not proposal_info) to preserve omitLargeFields.

Copilot AI review requested due to automatic review settings May 29, 2026 13:54
@yhabib yhabib requested a review from a team as a code owner May 29, 2026 13:54
@github-actions
Copy link
Copy Markdown

📊 Build Bundle Stats

The latest build generated the following assets:

dist/index.html                                           1.92 kB │ gzip:   0.68 kB
dist/assets/index-DxfLsNC8.css                          132.17 kB │ gzip:  20.82 kB
dist/assets/externalServices-B9hWFV-7.js                  0.21 kB │ gzip:   0.17 kB
dist/assets/Spinner-DsTlS527.js                           0.58 kB │ gzip:   0.40 kB
dist/assets/useTvlValue-ChOBCL_-.js                       0.58 kB │ gzip:   0.39 kB
dist/assets/service-DKHDVZh8.js                           0.60 kB │ gzip:   0.39 kB
dist/assets/useHideBalances-BjeLNmj0.js                   0.61 kB │ gzip:   0.40 kB
dist/assets/numbers-CDyCq99L.js                           0.61 kB │ gzip:   0.37 kB
dist/assets/PageHeader-Cr3cEbbs.js                        0.75 kB │ gzip:   0.44 kB
dist/assets/Separator-CV37vDbj.js                         0.77 kB │ gzip:   0.46 kB
dist/assets/CertifiedBadge-U1KIZqGq.js                    0.80 kB │ gzip:   0.48 kB
dist/assets/useIcpIndex-BLxs7U3X.js                       1.08 kB │ gzip:   0.63 kB
dist/assets/addressBook-D_voKsjK.js                       1.10 kB │ gzip:   0.70 kB
dist/assets/useCommandPaletteSettings-8vgFMN2e.js         1.64 kB │ gzip:   0.80 kB
dist/assets/Switch-C4IZA2NK.js                            1.65 kB │ gzip:   0.82 kB
dist/assets/CopyButton-DExm4lbH.js                        1.86 kB │ gzip:   0.95 kB
dist/assets/AnimatedNumber-i2WTQX9q.js                    1.86 kB │ gzip:   1.04 kB
dist/assets/useGovernanceAppCanister-BDjVp7wJ.js          1.92 kB │ gzip:   0.97 kB
dist/assets/useInfiniteQueryThenUpdateCall-BU-xvmIH.js    1.93 kB │ gzip:   0.96 kB
dist/assets/ToggleGroup-CLYvQcZF.js                       3.05 kB │ gzip:   1.33 kB
dist/assets/useTickerPrices-BADBYprb.js                   3.17 kB │ gzip:   1.51 kB
dist/assets/AmountInput-Bjz9Omq7.js                       6.37 kB │ gzip:   2.91 kB
dist/assets/useSpamFilterCanister-9t9GiXXM.js             7.20 kB │ gzip:   3.24 kB
dist/assets/QueryStates-BpH9nt2p.js                       7.95 kB │ gzip:   2.27 kB
dist/assets/index-DSsk7_7v.js                             8.78 kB │ gzip:   3.41 kB
dist/assets/Input-aKXfIMPU.js                             9.40 kB │ gzip:   3.35 kB
dist/assets/types-dHhmIFru.js                             9.96 kB │ gzip:   4.32 kB
dist/assets/TopicFollowingAccordion-DU1BgY2I.js          10.15 kB │ gzip:   4.05 kB
dist/assets/index-D_XtIb6z.js                            14.67 kB │ gzip:   4.69 kB
dist/assets/_auth-C7mQlYDG.js                            17.10 kB │ gzip:   6.51 kB
dist/assets/index-Bm1XmDql.js                            23.48 kB │ gzip:   8.06 kB
dist/assets/DepositICPModal-Ddgq7piP.js                  39.67 kB │ gzip:  13.88 kB
dist/assets/index-CCkhsu8v.js                            41.83 kB │ gzip:  11.86 kB
dist/assets/index-CC_IE_pU.js                            49.75 kB │ gzip:  15.02 kB
dist/assets/index-CJF4hAQC.js                            67.21 kB │ gzip:  20.67 kB
dist/assets/vendor-md-CeKJeCNV.js                        89.32 kB │ gzip:  25.51 kB
dist/assets/index-CSnZ2dr7.js                           122.56 kB │ gzip:  34.65 kB
dist/assets/index-CWyW98Pn.js                           123.95 kB │ gzip:  40.26 kB
dist/assets/vendor-tanstack-dUF9ZPhg.js                 126.65 kB │ gzip:  39.34 kB
dist/assets/vendor-core-react-By6K7kM9.js               193.24 kB │ gzip:  60.69 kB
dist/assets/vendor-recharts-DmT8shOr.js                 228.10 kB │ gzip:  65.92 kB
dist/assets/vendor-icp-B-t-gTJv.js                      404.22 kB │ gzip: 100.21 kB
dist/assets/vendor-libs-SlEJfvxd.js                     553.84 kB │ gzip: 183.40 kB

@zeropath-ai
Copy link
Copy Markdown

zeropath-ai Bot commented May 29, 2026

No security or compliance issues detected. Reviewed everything up to 094a7e1.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► src/governance-app-frontend/src/common/hooks/governance/useGovernanceProposal.ts
    Add ProposalInfo and isNullish imports
    Implement logic to filter proposals by ID
► src/governance-app-frontend/src/routes/_auth/voting/proposals/$id/index.tsx
    Update ProposalInfo type to handle undefined
    Conditionally render proposal details if proposal is defined

Copy link
Copy Markdown
Contributor

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 fixes proposal detail routing so missing or intentionally omitted proposal IDs show the existing not-found state instead of rendering the nearest lower proposal returned by list_proposals.

Changes:

  • Filters listProposals results in useGovernanceProposal to only return proposals matching the requested ID.
  • Updates the proposal details route types/render guard to handle an undefined proposal response.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/governance-app-frontend/src/common/hooks/governance/useGovernanceProposal.ts Adds ID matching before returning a proposal from the range query.
src/governance-app-frontend/src/routes/_auth/voting/proposals/$id/index.tsx Allows undefined proposal responses and avoids rendering details when absent.

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

@yhabib yhabib added this pull request to the merge queue May 29, 2026
Merged via the queue into main with commit 0002591 May 29, 2026
15 checks passed
@yhabib yhabib deleted the fix/proposal-not-found-fallback branch May 29, 2026 14:12
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.

3 participants