You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: add 403 scope guidance to issue list error handling (CLI-97)
When issue list gets 403 Forbidden, the error now includes suggestions
about token scopes, re-authentication, and project membership — matching
the 403 guidance added to org listing in PR #498.
Applied to both code paths (handleResolvedTargets and org-all mode).
Extracted enrichIssueListError() helper to DRY the 400/403 enrichment
used by both paths.
Affects 41 users (CLI-97).
* **Install script: BSD sed and awk JSON parsing breaks OCI digest extraction**: The install script parses OCI manifests with awk (no jq). Key trap: BSD sed \`\n\` is literal, not newline. Fix: single awk pass tracking last-seen \`"digest"\`, printing when \`"org.opencontainers.image.title"\` matches target. The config digest (\`sha256:44136fa...\`) is a 2-byte \`{}\` blob — downloading it instead of the real binary causes \`gunzip: unexpected end of file\`.
* **Multi-region fan-out: distinguish all-403 from empty orgs with hasSuccessfulRegion flag**: The multi-region org listing fan-out (\`listOrganizationsUncached\` in \`src/lib/api/organizations.ts\`) uses \`Promise.allSettled\` to collect results from all regions. When checking whether to propagate a 403 error, don't use \`flatResults.length === 0\` alone — a region returning 200 OK with zero orgs pushes nothing into \`flatResults\`, making it look like all regions failed. Track a separate \`hasSuccessfulRegion\` boolean set on any \`"fulfilled"\` settlement. Only re-throw the 403 \`ApiError\` when \`!hasSuccessfulRegion && lastScopeError\` — this correctly distinguishes "all regions returned 403" from "some regions had no orgs."
* **Multiple mockFetch calls replace each other — use unified mocks for multi-endpoint tests**: Bun test mocking gotchas: (1) \`mockFetch()\` replaces \`globalThis.fetch\` — calling it twice replaces the first mock. Use a single unified fetch mock dispatching by URL pattern. (2) \`mock.module()\` pollutes the module registry for ALL subsequent test files. Tests using it must live in \`test/isolated/\` and run via \`test:isolated\`. This also causes \`delta-upgrade.test.ts\` to fail when run alongside \`test/isolated/delta-upgrade.test.ts\` — the isolated test's \`mock.module()\` replaces \`CLI\_VERSION\` for all subsequent files. (3) For \`Bun.spawn\`, use direct property assignment in \`beforeEach\`/\`afterEach\`.
* **Cursor Bugbot review comments: fix valid bugs before merging**: Cursor Bugbot sometimes catches real logic bugs in PRs (not just style). In CLI-89, Bugbot identified that \`flatResults.length === 0\` was an incorrect proxy for "all regions failed" since fulfilled-but-empty regions are indistinguishable from rejected ones. Always read Bugbot's full comment body (via \`gh api repos/OWNER/REPO/pulls/NUM/comments\`) and fix valid findings before merging. Bugbot comments include a \`BUGBOT\_BUG\_ID\` HTML comment for tracking.
0 commit comments