Skip to content

SP-2668: Allow profile recovery when the default profile cannot refresh - #426

Merged
Zgjim Haziri (ZgjimHaziri) merged 3 commits into
mainfrom
SP-2668-profile-recovery
Sep 17, 2026
Merged

Zgjim Haziri (ZgjimHaziri) merged 3 commits into
mainfrom
SP-2668-profile-recovery

Conversation

@ZgjimHaziri

@ZgjimHaziri Zgjim Haziri (ZgjimHaziri) commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Description

An expired default OAuth profile whose refresh failed made every content-cli subcommand unusable — including profile create and profile list, the commands the error message told users to run.

A failed refresh reported itself with logger.error(new FatalError(...)), and the logger's custom transport exits the process on any record carrying an error. Because the execution context loads the default profile before Commander dispatches the subcommand, the process died before any command ran.

refreshProfile now warns and throws instead. Startup finishes with no profile, so profile management works; commands that need a connection still fail on first use of the HTTP client.

Relevant links

Checklist

  • I have self-reviewed this PR
  • I have tested the change and proved that it works in different scenarios
  • I have updated docs if needed

@ZgjimHaziri
Zgjim Haziri (ZgjimHaziri) force-pushed the SP-2668-profile-recovery branch 2 times, most recently from ece82ee to 96c6aee Compare September 15, 2026 15:24
A failed token refresh reported the failure with logger.error(new FatalError),
and the logger's custom transport calls process.exit(1) on any record carrying
an error. Because the execution context loads the default profile before
Commander dispatches the subcommand, the process died before any command ran --
including profile create and profile list, which the error message told the
user to run. The only way out was pointing --profile at a name that does not
exist.

refreshProfile now warns and throws instead. Context.loadProfile already
tolerates a rejected profile load, so startup finishes with no profile and
profile management works; commands that need a connection still fail on first
use of the http client.

The guard now wraps issuer discovery too, so an unreachable team gets the same
guidance as a rejected refresh token. The underlying cause is logged as text
rather than as the error object, because a raw network error carries errno and
the custom transport exits on that.

Includes-AI-Code: true
Co-authored-by: Cursor <cursoragent@cursor.com>
@ZgjimHaziri
Zgjim Haziri (ZgjimHaziri) marked this pull request as ready for review September 15, 2026 16:06
@ZgjimHaziri
Zgjim Haziri (ZgjimHaziri) requested a review from a team as a code owner September 15, 2026 16:06
The execution context loaded the default profile before Commander dispatched
the subcommand, so every invocation refreshed the stored token -- including
profile list and profile create, which never talk to the platform. A profile
that could not refresh therefore warned on commands that had no use for it.

Profile loading now runs in a preAction hook, and commands opt out with
skipProfileLoading(). Subcommands inherit the opt-out by walking up the parent
chain, so the profile and git profile families are marked once each and run
without touching the stored profile. Commands that need a connection load it
as before.

The hook is wired in run() rather than createProgram() because tests build
programs through createProgram with a hand-assembled context; registering it
there would make every command test load the developer's real default profile
and try to refresh it over the network.

The recovery warning no longer names a command to run.

Includes-AI-Code: true
Co-authored-by: Cursor <cursoragent@cursor.com>
Sonar flags the fluent builder on new code; the sibling methods predate the
quality gate and keep their concrete return type.

Includes-AI-Code: true
Co-authored-by: Cursor <cursoragent@cursor.com>
@sonarqubecloud

Copy link
Copy Markdown

@ZgjimHaziri
Zgjim Haziri (ZgjimHaziri) merged commit 2f01f3e into main Sep 17, 2026
5 checks passed
@ZgjimHaziri
Zgjim Haziri (ZgjimHaziri) deleted the SP-2668-profile-recovery branch September 17, 2026 14:38
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.

2 participants