Repository navigation
Give missing-scope errors the right next step - #182
Merged
Merged
Conversation
A missing-scope 403 used to tell every stored session to sign in again and passed through the API's "reach out to developer@" text, neither of which helps when the scope isn't in the CLI's OAuth grant. The error now names the scopes in missing_scopes and the API's shape in category, says whether signing in again can add each scope, and points to gusto feedback when it can't. Explicit tokens keep their replace-the-token advice. details only carries unrelated errors from the same response. Signed-off-by: tmfahey <taylor.fahey@gusto.com>
tmfahey
marked this pull request as ready for review
October 22, 2026 16:39
On newer Ubuntu runners /bin/echo is a link into the multi-call Rust coreutils binary, which picks its command from argv[0]. Copied to the upgrade's staging name it exits 1 with "unknown program", so the test failed for a reason unrelated to the upgrade path it covers. Signed-off-by: tmfahey <taylor.fahey@gusto.com>
cbento-gusto
approved these changes
Oct 22, 2026
cbento-gusto
left a comment
Contributor
There was a problem hiding this comment.
This change gives a CLI user a scope error they can act on. The grantable and ungrantable split is clear, the API's partner-facing text no longer leaks through, and the tests cover the mixed, plural, unnamed, and explicit-token cases well.
Checked and clear:
- Callers that read
error.details(clarifyVersionConflict,clarifyEmptyTimesheetSync) gate onExitCode.ApiClient, so the trimmeddetailson anAuthexit does not reach them. - Production
ApiClients always carryauth, so the newcase undefinedgrouping only changes test-only paths. scopesFromBodydedupes Gusto entries, drops empty names, and falls back to the RFC 6750scopein the same orderscopeErrorCategoryuses.nonScopeDetailskeeps unrelated errors, and human mode still prints them asreason:.
Blockers: None.
🤖 for @cbento-gusto
10 tasks done
jeff-gusto
added a commit
that referenced
this pull request
Oct 28, 2026
## Summary - Bumps the root package version and public version examples from `0.4.0` to `0.5.0`. - Prepares `v0.5.0` for the missing-scope error changes (#182) and the upgrade changes that keep `gusto upgrade` and auto-update working through the repo's move between orgs (#185). The upgrade change only reaches installed binaries once they update to a release that contains it, so this should be released promptly. ## Linked issue None. ## Test plan - [x] `env -u NO_COLOR bun run test:all` passes locally - [x] Manual run of touched commands works against sandbox — not applicable; this changes only version metadata and documentation - [x] `--agent` and `--human` output verified where touched — not applicable; this changes no output behavior - [x] `tsc --noEmit` - [x] `bun run lint` - [x] `bun run format:check` - [x] `bun run license:check` - [x] `bun run build` - [x] Compiled binary reports `0.5.0` ## DCO - [x] Every commit is signed off (`git commit -s`) per the [DCO](https://github.com/Gusto/gusto-cli/blob/main/CONTRIBUTING.md#developer-certificate-of-origin) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Jeff Stephens <jeff.stephens@gusto.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
insufficient_scopeerror now lists the scopes the API named inmissing_scopesand the error shape incategory. For a stored session, the message says which scopes signing in again can add. For any it can't add, it points togusto feedback.REQUIRED_SCOPESor the newRETAINED_SCOPES. Tokens fromGUSTO_ACCESS_TOKENor--token-stdinkeep the replace-the-token advice.detailsnow carries only unrelated errors from the same response. Every other 4xx and 5xx still gets the full body./bin/echois a multi-call coreutils binary that won't run under the staging file's name, so the test now copies Bun's own binary.Not in this PR:
timesheet,feedback) still suggest re-login on a scope error.details. I haven't seen the API send that shape.Linked issue
AINT-1118
Test plan
bun run test:allpasses locally--agentand--humanoutput verified where touchedAgainst sandbox I ran the grantable, outside-the-grant, env-token, stdin-token and 404 cases, in JSON and human output. I also ran the built binary against a local stub through
api requestandpayroll listfor the edge cases: no scope named, mixed scopes, RFC scope lists, empty scope names, and plain 403/422/500. None of the output contained developer@gusto.com.DCO
git commit -s) per the DCO