Skip to content

Comments

fix: improve error quality and prevent token leak in telemetry#279

Merged
BYK merged 2 commits intomainfrom
byk/fix-0.11.0-p0-p1-bugs-v2
Feb 23, 2026
Merged

fix: improve error quality and prevent token leak in telemetry#279
BYK merged 2 commits intomainfrom
byk/fix-0.11.0-p0-p1-bugs-v2

Conversation

@BYK
Copy link
Member

@BYK BYK commented Feb 23, 2026

Summary

Fixes three of the highest-impact issues from the 0.11.0 release (sourced from Sentry production data).

fix(issue): actionable error when issue not found by numeric ID (CLI-N)

118 events / 41 users

getIssue() surfaces a bare 404 as a generic message with no indication of which ID failed. Users often confuse numeric Sentry group IDs (which require access) with short-ID suffixes (which are human-readable).

Now resolveIssue() catches the 404 in both the numeric and explicit-org-numeric cases and re-throws a ContextError with:

  • The exact ID that wasn't found
  • A note that access may be missing or the issue may be deleted
  • A suggestion to try the <project>-<id> short-ID format

fix(telemetry): redact --token value from telemetry tags (CLI-19)

Security — token values were being sent to Sentry

setFlagContext() in telemetry.ts was forwarding the raw value of every flag as a flag.<name> tag. For sentry auth login --token sntrys_..., this meant the actual API token was appearing in the flag.token tag on every telemetry event.

Adds a SENSITIVE_FLAGS set (currently: token) and replaces those tag values with [REDACTED] before the tag is set.

fix(issue list): validate --cursor format before hitting the API (CLI-7H/7P/7B)

21 events / 12 users — 400 Bad Request from API

--cursor 100 (a plain integer) was forwarded directly to the API, which rejects it. Cursor values are opaque strings like 1735689600:0:0. Plain-integer inputs are now rejected at parse time with a message explaining the expected format.

Note: the --limit part of this bug is already addressed on main via auto-pagination (#274).

Three fixes targeting the highest-impact issues from the 0.11.0 release:

- fix(issue): include issue ID in 'not found' error and suggest short-ID
  format (CLI-N, 118 events / 41 users). Catches 404 from getIssue() in
  both the 'numeric' and 'explicit-org-numeric' resolveIssue() cases and
  re-throws a ContextError with the ID and a hint to try <project>-<id>.

- fix(telemetry): redact --token value from telemetry tags (CLI-19,
  security). setFlagContext() now replaces values of sensitive flags
  (currently: token) with '[REDACTED]' before calling Sentry.setTag().

- fix(issue list): validate --cursor format early (CLI-7H/7P/7B). Cursor
  values that are plain integers are now rejected at parse time with a
  message explaining the expected format. The --limit issue is already
  addressed on main via auto-pagination (#274).
@github-actions
Copy link
Contributor

github-actions bot commented Feb 23, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


Bug Fixes 🐛

  • (fetch) Preserve Content-Type header for SDK requests on Node.js by BYK in #276
  • (help) Document target patterns and trailing-slash significance by BYK in #272
  • (issue-list) Auto-paginate --limit beyond 100 by BYK in #274
  • (npm) Add Node.js >= 22 version guard to npm bundle by BYK in #269
  • (telemetry) Fix commands importing buildCommand directly from @stricli/core by BYK in #275
  • Improve error quality and prevent token leak in telemetry by BYK in #279

Internal Changes 🔧

  • (org) Use shared list-command constants in org list by BYK in #273

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 23, 2026

Codecov Results 📊

✅ Patch coverage is 100.00%. Project has 3591 uncovered lines.
✅ Project coverage is 74.71%. Comparing base (base) to head (head).

Files with missing lines (69)
File Patch % Lines
human.ts 58.39% ⚠️ 394 Missing
resolve-target.ts 37.26% ⚠️ 325 Missing
api-client.ts 70.70% ⚠️ 242 Missing
oauth.ts 30.94% ⚠️ 183 Missing
list.ts 30.18% ⚠️ 155 Missing
plan.ts 19.37% ⚠️ 154 Missing
list.ts 73.74% ⚠️ 125 Missing
resolver.ts 3.23% ⚠️ 120 Missing
help.ts 19.85% ⚠️ 109 Missing
upgrade.ts 61.37% ⚠️ 107 Missing
view.ts 41.90% ⚠️ 104 Missing
interactive-login.ts 9.17% ⚠️ 99 Missing
errors.ts 5.94% ⚠️ 95 Missing
view.ts 25.81% ⚠️ 92 Missing
view.ts 41.50% ⚠️ 86 Missing
clipboard.ts 4.49% ⚠️ 85 Missing
status.ts 24.07% ⚠️ 82 Missing
migration.ts 47.44% ⚠️ 82 Missing
list.ts 21.88% ⚠️ 75 Missing
browser.ts 4.11% ⚠️ 70 Missing
list.ts 86.12% ⚠️ 59 Missing
span-tree.ts 5.00% ⚠️ 57 Missing
explain.ts 33.33% ⚠️ 56 Missing
api.ts 89.80% ⚠️ 47 Missing
upgrade.ts 66.91% ⚠️ 46 Missing
seer.ts 75.54% ⚠️ 45 Missing
schema.ts 91.51% ⚠️ 40 Missing
refresh.ts 40.63% ⚠️ 38 Missing
seer.ts 79.87% ⚠️ 30 Missing
preload.ts 53.23% ⚠️ 29 Missing
view.ts 87.39% ⚠️ 28 Missing
telemetry.ts 93.09% ⚠️ 27 Missing
view.ts 61.54% ⚠️ 25 Missing
fix.ts 89.43% ⚠️ 24 Missing
org-list.ts 93.60% ⚠️ 22 Missing
utils.ts 91.39% ⚠️ 21 Missing
detector.ts 90.10% ⚠️ 20 Missing
arg-parsing.ts 90.67% ⚠️ 18 Missing
binary.ts 88.67% ⚠️ 17 Missing
help.ts 57.14% ⚠️ 15 Missing
sentry-client.ts 92.49% ⚠️ 13 Missing
dsn-cache.ts 94.62% ⚠️ 12 Missing
code-scanner.ts 96.25% ⚠️ 12 Missing
logout.ts 56.00% ⚠️ 11 Missing
token.ts 52.17% ⚠️ 11 Missing
qrcode.ts 33.33% ⚠️ 10 Missing
fs-utils.ts 57.14% ⚠️ 9 Missing
view.ts 94.89% ⚠️ 7 Missing
project-root.ts 97.73% ⚠️ 7 Missing
version-check.ts 92.47% ⚠️ 7 Missing
feedback.ts 84.21% ⚠️ 6 Missing
auth.ts 95.56% ⚠️ 6 Missing
shell.ts 96.23% ⚠️ 6 Missing
app.ts 94.05% ⚠️ 5 Missing
setup.ts 97.84% ⚠️ 4 Missing
project-aliases.ts 97.40% ⚠️ 2 Missing
project-root-cache.ts 96.92% ⚠️ 2 Missing
output.ts 89.47% ⚠️ 2 Missing
login.ts 98.72% ⚠️ 1 Missing
list.ts 99.03% ⚠️ 1 Missing
alias.ts 99.42% ⚠️ 1 Missing
completions.ts 99.37% ⚠️ 1 Missing
index.ts 98.99% ⚠️ 1 Missing
env-file.ts 99.19% ⚠️ 1 Missing
parser.ts 98.63% ⚠️ 1 Missing
colors.ts 98.21% ⚠️ 1 Missing
trace.ts 99.16% ⚠️ 1 Missing
region.ts 97.30% ⚠️ 1 Missing
helpers.ts 94.74% ⚠️ 1 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    74.62%    74.71%    +0.09%
==========================================
  Files          115       115         —
  Lines        14167     14200       +33
  Branches         0         0         —
==========================================
+ Hits         10572     10609       +37
- Misses        3595      3591        -4
- Partials         0         0         —

Generated by Codecov Action

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

throw new ContextError(`Issue ${parsed.id}`, commandHint, [
`No issue with numeric ID ${parsed.id} found — you may not have access, or it may have been deleted.`,
`If this is a short ID suffix, try: sentry issue ${command} <project>-${parsed.id}`,
]);
Copy link

Choose a reason for hiding this comment

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

ContextError produces misleading "is required" for 404

Medium Severity

ContextError formats its first argument via buildContextMessage as "{resource} is required.", so passing "Issue ${parsed.id}" produces the message "Issue 12345 is required." followed by "Specify it using: sentry issue show <org>/12345". This is misleading for a 404 not-found error — the user did provide the issue ID, it just wasn't found. The actual helpful explanation ends up buried under the "Or:" section. Since this PR's goal is to improve error quality for these 404s, the use of ContextError undermines the intent.

Additional Locations (1)

Fix in Cursor Fix in Web

const USAGE_HINT = "sentry issue list <org>/<project>";

/** Matches strings that are all digits — used to detect invalid cursor values */
const ALL_DIGITS_RE = /^\d+$/;
Copy link

Choose a reason for hiding this comment

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

Redundant regex duplicates existing isAllDigits utility

Low Severity

The new ALL_DIGITS_RE constant (/^\d+$/) is an exact duplicate of ALL_DIGITS_PATTERN in src/lib/utils.ts, which is already exposed as the isAllDigits() utility function. That same utility is already imported and used in the sibling file src/commands/issue/utils.ts. The cursor validation at line 747 could simply call isAllDigits(value) instead of introducing a second copy of the regex.

Additional Locations (1)

Fix in Cursor Fix in Web

…r validation

- test(issue/utils): 4 tests for resolveIssue() numeric and
  explicit-org-numeric 404 cases: ContextError thrown with ID + hint,
  non-404 errors propagate unchanged

- test(telemetry): 3 tests for setFlagContext() SENSITIVE_FLAGS: token
  value is replaced with '[REDACTED]', tag is still set (presence signal
  preserved), non-sensitive flags alongside token are unaffected

- test(issue/list): 4 tests for cursor flag parse function: 'last'
  accepted, valid opaque cursors accepted, plain integers rejected with
  descriptive error including the bad value and an example format
@BYK BYK merged commit 22d5f39 into main Feb 23, 2026
23 checks passed
@BYK BYK deleted the byk/fix-0.11.0-p0-p1-bugs-v2 branch February 23, 2026 15:06
BYK added a commit that referenced this pull request Feb 23, 2026
## Summary

- Fixes **CLI-7W**: Users passing a numeric Sentry project ID (e.g.,
`sentry event view 7275560680 <event-id>`) got a confusing "Project not
found" error
- Also resolves **CLI-80** as already fixed by PR #279 (cursor format
validation)

## Changes

**`findProjectsBySlug` (api-client.ts):** When the input is all-digits,
accept the API result even when the returned slug differs from the
input. The Sentry API's `project_id_or_slug` parameter already resolves
numeric IDs — the CLI just wasn't accepting those results.

**`resolveProjectBySlug` (resolve-target.ts):** 
- When a numeric ID resolves successfully, prints a stderr hint: `Tip:
Resolved project ID 7275560680 to acme/frontend. Use the slug form for
faster lookups.`
- When resolution fails with an all-digit input, the error message says
"Numeric project IDs are not supported" instead of the generic "Check
that you have access"

**View commands:** Pass `this.stderr` to `resolveProjectBySlug` so the
hint can be displayed.

## Testing

- 2 new tests for `findProjectsBySlug`: numeric ID resolution accepted,
non-numeric slug mismatch still rejected
- 1 updated test for `project view` func (new `stderr` parameter)
- All 2010 tests pass
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.

1 participant