fix(init): add --app flag and actionable errors for non-interactive monorepo runs#977
Merged
Conversation
…onorepo runs
When running `sentry init --yes --features errors` against a monorepo,
the wizard suspended for app selection, received `{ cancelled: true }` as
resume data, and the server returned a bare HTTP 500 because `selectedApp`
was required. The root causes:
- No flag existed to pre-select an app in non-interactive mode
- handleSelect returned { cancelled: true } instead of throwing, so
malformed resume data reached the server
- The one-liner error didn't name the available apps or show a fix
This adds --app to allow non-interactive app selection and rewrites
handleSelect to throw with a formatted list of apps and the exact
re-run command. The default branch in handleInteractive also now throws
instead of returning the sentinel. A guard in handleSuspendedStep
catches any future { cancelled: true } return before it reaches the
server.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Contributor
|
Three tests expected { cancelled: true } return values that the
refactored handlers now throw as WizardError instead.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Contributor
Codecov Results 📊✅ 6986 passed | Total: 6986 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
All tests are passing successfully. ✅ Patch coverage is 85.39%. Project has 14236 uncovered lines. Files with missing lines (2)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
- Coverage 77.15% 76.99% -0.16%
==========================================
Files 320 320 —
Lines 61662 61873 +211
Branches 0 0 —
==========================================
+ Hits 47572 47637 +65
- Misses 14090 14236 +146
- Partials 0 0 —Generated by Codecov Action |
Three follow-ups for #977: - Guard the --app matching branch on payload.apps being present and non-empty, so the flag only activates for the monorepo app-selection prompt and is silently ignored on any other select-kind payload - Fix import sort order in interactive.test.ts (WizardError before handleInteractive) to satisfy Biome's organizeImports rule - Add five tests covering the --app happy path, case-insensitive matching, not-found error content, non-monorepo passthrough, and multi-app error message content — brings interactive.ts to 100% function coverage and 99% line coverage Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
The if (options.yes) block that throws the "This monorepo has N apps" error was missing the same payload.apps guard added for --app in the previous commit. A non-monorepo select prompt with multiple options and --yes set would hit this path and show a completely wrong error suggesting the user is in a monorepo and needs --app. Guard is now: options.yes && payload.apps && payload.apps.length > 0, symmetric with the --app guard above it. Without apps present the block is skipped and falls through to ui.select() as expected. Updates existing test to include payload.apps so it still covers the monorepo error path. Adds a new test confirming --yes with a plain options-only select falls through without error. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2445a17. Configure here.
"No apps found in this monorepo." was wrong when payload.apps is absent and the empty options list came from a non-monorepo select prompt. Message is now context-neutral. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…omment The interactive app picker built select options with apps[i] (index-based) while formatAppList already used apps.find(a => a.name === item) after the alignment fix. Consistent name-based lookup throughout so framework hints stay correct regardless of whether payload.options and payload.apps have the same ordering or length. Also trims the formatAppList comment to the why, dropping the redundant "how" sentence. Co-Authored-By: Claude Sonnet 4.6 (1M context) <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.

Running
sentry init --yes --features errorsagainst a monorepo would hit theselect-target-appstep, fail to resolve an app non-interactively, and send{ cancelled: true }as resume data to the server. The server validated it against a schema requiringselectedAppand returned HTTP 500. Users saw:Three root causes fixed here:
1. No non-interactive escape hatch. Added
--app <name>flag so CI/agent runs can specify which monorepo app to initialize. Case-insensitive match against the server-provided app list.2.
handleSelectreturned instead of throwing. When--yeswas set with multiple apps, it returned{ cancelled: true }which got forwarded to the server as resume data. It now throws with a formatted app list and the exact re-run command:3. Safety net. Added a guard in
handleSuspendedStepthat throws before any{ cancelled: true }result can reachresumeWithRetry, so a future regression fails on the CLI side rather than producing an opaque server error.Also fixed the
defaultbranch inhandleInteractive(same{ cancelled: true }bug for unknown prompt kinds) and rewroteformatAppListto iterate overitemsrather thanappsso the list stays correct ifpayload.optionsandpayload.appsever arrive at different lengths.Closes CLI-17A (77 events, all
is_tty: False+flag.yes: True).