Skip to content

Improve auth token error formatting for easier copy-paste#5115

Open
jamesbroadhead wants to merge 4 commits into
mainfrom
fix-auth-login-error-formatting
Open

Improve auth token error formatting for easier copy-paste#5115
jamesbroadhead wants to merge 4 commits into
mainfrom
fix-auth-login-error-formatting

Conversation

@jamesbroadhead

Copy link
Copy Markdown
Contributor

Replaces #4602 — re-opened from an upstream branch (was previously from a fork, which blocked CI from running properly). Original PR was approved by @andrewnester and @simonfaltum.

Changes

Format the auth token error message across multiple lines so the
suggested databricks auth login command is on its own line and easy
to copy-paste.

Before:

Error: cache: databricks OAuth is not configured for this host. Try logging in again with `databricks auth login --host https://example.com` before retrying. If this fails, please report this issue to the Databricks CLI maintainers at https://github.com/databricks/cli/issues/new

After:

Error: cache: databricks OAuth is not configured for this host.

To reauthenticate, run the following command:

  $ databricks auth login --host https://example.com

If this fails, please report this issue to the Databricks CLI maintainers at https://github.com/databricks/cli/issues/new

Why

When auth fails, the suggested login command was printed on the same line as the error and config details, making it difficult to select and copy. This follows the same multi-line pattern already used by RewriteAuthError for invalid refresh token errors.

Tests

  • Unit tests updated and passing (go test ./cmd/auth/ -run TestToken_loadToken)
  • Acceptance test golden file updated and passing (go test ./acceptance/... -run TestAccept/cmd/auth/token)

@github-actions

github-actions Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Approval status: pending

/cmd/auth/ - needs approval

Files: cmd/auth/token.go, cmd/auth/token_test.go
Suggested: @simonfaltum
Also eligible: @mihaimitrea-db, @tanmay-db, @renaudhartert-db, @hectorcast-db, @parthban-db, @Divyansh-db, @tejaskochar-db, @chrisst, @rauchy

/cmd/root/ - needs approval

Files: cmd/root/auth.go
Suggested: @simonfaltum
Also eligible: @mihaimitrea-db, @tanmay-db, @renaudhartert-db, @hectorcast-db, @parthban-db, @Divyansh-db, @tejaskochar-db, @chrisst, @rauchy

/libs/auth/ - needs approval

Files: libs/auth/error.go, libs/auth/error_test.go
Suggested: @simonfaltum
Also eligible: @mihaimitrea-db, @tanmay-db, @renaudhartert-db, @hectorcast-db, @parthban-db, @Divyansh-db, @tejaskochar-db, @chrisst, @rauchy

General files (require maintainer)

Files: NEXT_CHANGELOG.md, acceptance/cmd/auth/token/force-refresh-invalid-refresh-token/output.txt
Based on git history:

  • @simonfaltum -- recent work in cmd/auth/, ./, libs/auth/

Any maintainer (@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db) can approve all areas.
See OWNERS for ownership rules.

@simonfaltum simonfaltum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Two small findings from review. The auth behavior mostly looks aligned with the existing code; these are the pieces I think should be cleaned up before merge.

Comment thread NEXT_CHANGELOG.md Outdated

* `databricks api` now works against unified hosts. Adds `--account` to scope a call to the account API and `--workspace-id` to override the workspace routing identifier per call. A `?o=<workspace-id>` query parameter on the path (the SPOG URL convention used by the Databricks UI) is also recognized as a per-call workspace override, so URLs pasted from the browser route correctly.

* Improve `auth token` error formatting for easier copy-paste of login commands ([#4602](https://github.com/databricks/cli/pull/4602))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This link still points to the replaced PR (#4602). Since this PR is the one that will merge, the release note should reference #5115; otherwise the shipped changelog sends readers to the abandoned PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here, working with James. Fixed — NEXT_CHANGELOG.md now links #5115 so the shipped release note points at the actually-merged PR (see latest push, rebased onto current main).

Comment thread libs/auth/error.go
return
}
fmt.Fprintf(b, "\n - Re-authenticate: %s", BuildLoginCommand(ctx, "", oauthArg))
fmt.Fprintf(b, "\n - Re-authenticate: %s", BuildLoginCommand(ctx, "", cfg.WorkspaceID, oauthArg))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This non-profile branch now gets the safer command construction, but the cfg.Profile != "" branch just above still formats databricks auth login --profile %s by hand. That means profile names with spaces or shell metacharacters still produce broken/unsafe copy-paste commands in EnrichAuthError. Can the profile branch use BuildLoginCommand(ctx, cfg.Profile, cfg.WorkspaceID, nil) too, or otherwise quote consistently?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here, working with James. Fixed — the DatabricksCli profile branch in writeReauthSteps now routes through BuildLoginCommand(ctx, cfg.Profile, "", nil), which shell-quotes the profile name (see libs/auth/error.go:132-134). The Pat and Basic profile branches were also using raw fmt.Fprintf and got the same treatment (lines 149/156). Locked the shell-quoting in with a "weird name" regression case in TestEnrichAuthError.

@simonfaltum simonfaltum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review summary

I ran a multi-agent review (Isaac + Cursor) on this reopened PR. Both reviewers converged on COMMENT with one important consistency gap.

The core auth token formatting change is correct and well-tested for the surface it touched, but the new BuildLoginCommand helper isn't used everywhere it should be — one sibling render path was missed.

Important:

  • writeReauthSteps's AuthTypeDatabricksCli profile branch still uses raw fmt.Fprintf(... "--profile %s", ...), bypassing the new helper. This is the most common 401 path. Result: it misses both --workspace-id and shell-quoting in exactly the workflow this PR is supposed to be normalizing.

Nits:

  • Changelog links the superseded #4602 instead of #5115
  • RewriteAuthError layout still single-paragraph vs helpfulError's blank-line-padded form
  • BuildLoginCommand doc-comment doesn't explain why Account/Workspace OAuth cases drop workspaceID
  • Test gaps: no negative assertion for omission, no shell-quoting test

Question:

  • Why include --workspace-id on the profile path? auth login --profile foo already picks up the profile's stored workspace_id — worth a one-line note in the doc-comment to explain the intent (pin to the workspace the failing call resolved against?).

For full context I left these as inline comments below.

Comment thread libs/auth/error.go
return
}
fmt.Fprintf(b, "\n - Re-authenticate: %s", BuildLoginCommand(ctx, "", oauthArg))
fmt.Fprintf(b, "\n - Re-authenticate: %s", BuildLoginCommand(ctx, "", cfg.WorkspaceID, oauthArg))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Important: the sibling profile branch (line 125) wasn't updated.

This branch correctly routes through BuildLoginCommand(ctx, "", cfg.WorkspaceID, oauthArg) now. But the if cfg.Profile != "" branch above (line 125 in the new file) still does fmt.Fprintf(b, "... --profile %s", cfg.Profile), bypassing the helper.

Result: a 401 on a profile-based databricks-cli call (the most common case) renders without --workspace-id and without shell-quoting, while this branch and the new helpfulError path do both. That makes the PR's own consistency claim only half-true — and on unified/SPOG hosts the suggested command can target the wrong workspace.

Fix: route the profile branch through BuildLoginCommand(ctx, cfg.Profile, cfg.WorkspaceID, nil). Add a test using a profile with WorkspaceID set, and ideally a profile name needing shell-quoting (e.g. with a space) to cover both improvements at once.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here, working with James.

Good catch — the DatabricksCli profile branch was already routed through BuildLoginCommand in 089769a, so that specific bypass is gone. The same gap existed in the Pat and Basic branches (line 144 / 151), which still emitted databricks auth login --profile %s via raw fmt.Fprintf. Fixed those in e398f44 and added a regression test with Profile = "weird name" to lock in the shell-quoting.

(Side note: with --workspace-id dropped on the profile path, the consistency argument from your original comment is now moot — only the shell-quoting bit needed addressing.)

Thanks again.

Comment thread NEXT_CHANGELOG.md Outdated

* `databricks api` now works against unified hosts. Adds `--account` to scope a call to the account API and `--workspace-id` to override the workspace routing identifier per call. A `?o=<workspace-id>` query parameter on the path (the SPOG URL convention used by the Databricks UI) is also recognized as a per-call workspace override, so URLs pasted from the browser route correctly.

* Improve `auth token` error formatting for easier copy-paste of login commands ([#4602](https://github.com/databricks/cli/pull/4602))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: this links the superseded #4602, but this branch will merge as #5115. Worth pointing release-note readers at the actual merged PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here, working with James. Fixed — the changelog entry now links #5115 (4889f4b, rebased onto current main).

Comment thread libs/auth/error.go Outdated
Comment on lines +68 to +69
msg := `A new access token could not be retrieved because the refresh token is invalid. To reauthenticate, run the following command:
$ ` + BuildLoginCommand(ctx, profile, oauthArgument)
$ ` + BuildLoginCommand(ctx, profile, workspaceId, oauthArgument)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: layout inconsistency.

RewriteAuthError keeps the legacy ...command:\n $ <cmd> shape, while the new helpfulError in cmd/auth/token.go uses a blank-line-padded layout (...command:\n\n $ <cmd>\n\n...). The PR description says the new format "matches the existing RewriteAuthError pattern," but they now diverge.

Compare acceptance/cmd/auth/token/force-refresh-invalid-refresh-token/output.txt (no blank lines around the command) with force-refresh-no-cache/output.txt (blank lines around the command).

Fix: unify on the new padded form here too — that's the actual goal of the PR. The acceptance test golden file would need a small update.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here, working with James. Unified on the blank-line-padded layout — RewriteAuthError now emits <msg>.\n\nTo reauthenticate, run the following command:\n\n $ <cmd> (see libs/auth/error.go:74-77). The force-refresh-invalid-refresh-token acceptance golden was regenerated to match, and the corresponding unit-test expectations in cmd/auth/token_test.go were updated.

Comment thread libs/auth/error.go
Comment on lines +165 to +173
// BuildLoginCommand builds the login command for the given OAuth argument or
// profile. Each argument is shell-quoted so the rendered command is safe to
// copy-paste even when host, profile, or account-id values contain spaces or
// shell metacharacters.
//
// workspaceID, when non-empty and not the WorkspaceIDNone sentinel, is
// emitted as --workspace-id for unified hosts so the suggested reauth
// targets the same workspace the failing call resolved against (the
// information the OAuthArgument otherwise drops).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: the doc-comment explains the unified-host case for --workspace-id but not the AccountOAuthArgument/WorkspaceOAuthArgument cases below, which intentionally drop workspaceID. This is correct (account args target the account API; workspace args identify a workspace by host already), but the asymmetry isn't called out and is easy to break in a future change.

Fix: add one sentence — "For AccountOAuthArgument and WorkspaceOAuthArgument, workspaceID is intentionally ignored since those argument types either target the account API or already identify a workspace by host."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here, working with James. Added the asymmetry note to BuildLoginCommand's doc-comment (see libs/auth/error.go:187-189): "For AccountOAuthArgument and WorkspaceOAuthArgument, workspaceID is also intentionally ignored: account args target the account API, and workspace args already identify a workspace via --host." Also documented the profile-path omission for symmetry (lines 183-185).

Comment thread libs/auth/error_test.go
Comment on lines +28 to +58
func TestBuildLoginCommand_AppendsWorkspaceID(t *testing.T) {
ctx := t.Context()

t.Run("profile path emits --workspace-id when set", func(t *testing.T) {
cmd := BuildLoginCommand(ctx, "dev", "12345", nil)
assert.Equal(t, "databricks auth login --profile dev --workspace-id 12345", cmd)
})

t.Run("profile path omits --workspace-id when empty", func(t *testing.T) {
cmd := BuildLoginCommand(ctx, "dev", "", nil)
assert.Equal(t, "databricks auth login --profile dev", cmd)
})

t.Run("profile path omits --workspace-id for the 'none' sentinel", func(t *testing.T) {
cmd := BuildLoginCommand(ctx, "dev", WorkspaceIDNone, nil)
assert.Equal(t, "databricks auth login --profile dev", cmd)
})

t.Run("unified host path emits --workspace-id when set", func(t *testing.T) {
oauthArg, err := AuthArguments{
Host: "https://unified.cloud.databricks.com",
AccountID: "acc-123",
DiscoveryURL: "https://unified.cloud.databricks.com/oidc/accounts/acc-123/.well-known/oauth-authorization-server",
}.ToOAuthArgument()
require.NoError(t, err)

cmd := BuildLoginCommand(ctx, "", "ws-456", oauthArg)
assert.Contains(t, cmd, "--account-id acc-123")
assert.Contains(t, cmd, "--workspace-id ws-456")
})
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: two coverage gaps in TestBuildLoginCommand_AppendsWorkspaceID:

  1. No negative assertion that AccountOAuthArgument/WorkspaceOAuthArgument paths omit --workspace-id even when one is provided. The production code does this intentionally; a regression test would lock that in.
  2. No shell-quoting test. All the existing cases use safe profile names (dev), so shellquote.BashArg is effectively untested. A profile name like "weird name" would cover the round-trip through the quoter.

Fix: two short table cases — one with WorkspaceOAuthArgument (e.g. classic https://adb-123.azuredatabricks.net) asserting --workspace-id is absent; one with profile = "weird name" asserting the output contains --profile 'weird name'. Both are one-liners.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here, working with James. Both gaps closed in TestBuildLoginCommand_AppendsWorkspaceID (see libs/auth/error_test.go:55-78, 80-83):

  1. Negative assertions on both WorkspaceOAuthArgument and AccountOAuthArgument paths: each builds the OAuth arg, calls BuildLoginCommand(ctx, "", "ws-456", oauthArg), and asserts --workspace-id is not present in the rendered command.
  2. Shell-quoting case with profile = "weird name" asserting the output is exactly databricks auth login --profile 'weird name'.

Both fixture hosts use .test TLDs with explicit DiscoveryURL so ToOAuthArgument doesn't trigger a real .well-known resolution (per the PR #5125 convention).

Comment thread cmd/auth/token.go
Comment on lines 278 to +281
allArgs = append(allArgs, u2m.WithOAuthArgument(oauthArgument))
persistentAuth, err := u2m.NewPersistentAuth(ctx, allArgs...)
if err != nil {
helpMsg := helpfulError(ctx, args.profileName, oauthArgument)
return nil, fmt.Errorf("%w. %s", err, helpMsg)
helpMsg := helpfulError(ctx, args.profileName, args.authArguments.WorkspaceID, oauthArgument)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Question: why include --workspace-id on the profile path?

When the user invokes databricks auth token --profile foo and we suggest databricks auth login --profile foo --workspace-id <id>, the --workspace-id is technically redundant — auth login --profile foo will already pick up the workspace_id stored in the profile.

Including it is meaningful only if (a) the profile's persisted workspace_id has drifted from the failing call's workspace_id, or (b) the user typed --workspace-id on the failing call and we want to preserve that intent. Both are plausible, but the doc-comment on BuildLoginCommand only motivates the unified-host case.

Not asking for a code change — just want to confirm this was deliberate. If yes, a one-line addendum to the doc-comment (e.g. "…also re-emitted on the profile path so the suggested reauth pins the same workspace_id the failing call resolved against") would close the loop.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here, working with James.

You're right — --workspace-id on the profile path was noise left over from a previous iteration of this PR (back when I was trying to pin the workspace explicitly across all branches before the unified-host logic landed). auth login --profile foo already picks up the stored workspace_id, so re-emitting it adds nothing and just clutters the suggested command.

Dropped it from BuildLoginCommand's profile branch and from writeReauthSteps in 368d919. The two affected acceptance goldens (force-refresh-no-cache, force-refresh-invalid-refresh-token) are refreshed.

Thanks for the review.

jamesbroadhead added a commit that referenced this pull request May 18, 2026
Reformats the `auth token` error so the suggested `databricks auth login`
command lands on its own line with blank-line padding above and below,
making it easy to select and copy. Also pulls every render path through
the new `BuildLoginCommand` helper so they all benefit from shell-quoting
and consistent --workspace-id emission.

Rebased onto current main; addresses simonfaltum's May 7 review:

- **Blocking fix**: `writeReauthSteps`'s `AuthTypeDatabricksCli` profile branch
  now routes through `BuildLoginCommand(ctx, cfg.Profile, cfg.WorkspaceID, nil)`
  instead of the raw `fmt.Fprintf(... "--profile %s", ...)`. Previously this
  branch (the most common 401 path) missed both shell-quoting and
  --workspace-id; on unified/SPOG hosts the suggested command could target
  the wrong workspace.
- Changelog link points at #5115 (was the superseded #4602).
- `RewriteAuthError` unified on the blank-line-padded layout to match
  `helpfulError`. Acceptance test golden file regenerated.
- `BuildLoginCommand` doc-comment expanded with two clarifications:
  (a) why the profile path re-emits --workspace-id (pin to the workspace
  the failing call resolved against, even if the profile's persisted
  value drifted), and (b) why Account/Workspace OAuth cases drop
  workspaceID (account args target the account API; workspace args
  already identify a workspace by host).
- Two new test cases on `TestBuildLoginCommand_AppendsWorkspaceID`:
  negative assertions that `WorkspaceOAuthArgument` and
  `AccountOAuthArgument` paths omit `--workspace-id` even when provided,
  plus a shell-quoting case (`profile = "weird name"`).

Co-authored-by: Isaac
@jamesbroadhead jamesbroadhead force-pushed the fix-auth-login-error-formatting branch from 45602a6 to 089769a Compare May 18, 2026 22:27
@jamesbroadhead

Copy link
Copy Markdown
Contributor Author

👋 @simonfaltum @andrewnester — Claude here on James's behalf.

Rebased onto current main and addressed all of Simon's May 7 review:

Blocking fix:

  • writeReauthSteps's AuthTypeDatabricksCli profile branch (line ~125 in the old diff) now routes through BuildLoginCommand(ctx, cfg.Profile, cfg.WorkspaceID, nil) instead of the raw fmt.Fprintf(... "--profile %s", ...). The most common 401 path now picks up shell-quoting and the workspace-id emission consistently with the host-based branch.

Nits:

  1. Changelog link now points at Improve auth token error formatting for easier copy-paste #5115 (was the superseded Improve auth token error formatting for easier copy-paste #4602).
  2. RewriteAuthError unified on the blank-line-padded layout to match helpfulError. The force-refresh-invalid-refresh-token acceptance golden file was regenerated to capture the new shape.
  3. BuildLoginCommand doc-comment expanded with the Account/Workspace OAuth asymmetry note + a sentence explaining why the profile path also re-emits --workspace-id.
  4. Two new test cases on TestBuildLoginCommand_AppendsWorkspaceID: negative assertions that WorkspaceOAuthArgument and AccountOAuthArgument paths omit --workspace-id even when one is provided, plus a shell-quoting case using profile = "weird name".

Re: your question on why --workspace-id is re-emitted on the profile path: the doc-comment now spells out the intent — pin the suggested reauth to the same workspace_id the failing call resolved against, even if the profile's persisted value has drifted from the env/flag value used in the failing call. Happy to tweak the wording if you'd prefer something different.

Diff against main: 10 files, +168/-43. Unit tests + the auth acceptance suite pass locally.

(comment posted by Claude)

@jamesbroadhead jamesbroadhead enabled auto-merge May 21, 2026 14:23
jamesbroadhead added a commit that referenced this pull request May 21, 2026
Reformats the `auth token` error so the suggested `databricks auth login`
command lands on its own line with blank-line padding above and below,
making it easy to select and copy. Also pulls every render path through
the new `BuildLoginCommand` helper so they all benefit from shell-quoting
and consistent --workspace-id emission.

Rebased onto current main; addresses simonfaltum's May 7 review:

- **Blocking fix**: `writeReauthSteps`'s `AuthTypeDatabricksCli` profile branch
  now routes through `BuildLoginCommand(ctx, cfg.Profile, cfg.WorkspaceID, nil)`
  instead of the raw `fmt.Fprintf(... "--profile %s", ...)`. Previously this
  branch (the most common 401 path) missed both shell-quoting and
  --workspace-id; on unified/SPOG hosts the suggested command could target
  the wrong workspace.
- Changelog link points at #5115 (was the superseded #4602).
- `RewriteAuthError` unified on the blank-line-padded layout to match
  `helpfulError`. Acceptance test golden file regenerated.
- `BuildLoginCommand` doc-comment expanded with two clarifications:
  (a) why the profile path re-emits --workspace-id (pin to the workspace
  the failing call resolved against, even if the profile's persisted
  value drifted), and (b) why Account/Workspace OAuth cases drop
  workspaceID (account args target the account API; workspace args
  already identify a workspace by host).
- Two new test cases on `TestBuildLoginCommand_AppendsWorkspaceID`:
  negative assertions that `WorkspaceOAuthArgument` and
  `AccountOAuthArgument` paths omit `--workspace-id` even when provided,
  plus a shell-quoting case (`profile = "weird name"`).

Co-authored-by: Isaac
@jamesbroadhead jamesbroadhead force-pushed the fix-auth-login-error-formatting branch from e398f44 to dc32561 Compare May 21, 2026 14:33
@jamesbroadhead

Copy link
Copy Markdown
Contributor Author

👋 @simonfaltum @andrewnester — Claude here on James's behalf.

Rebased onto current main (was DIRTY). The 3 commits on top of main are unchanged in intent; conflicts were in NEXT_CHANGELOG.md (re-keyed under the new v1.1.0 header with the #5115 link) and a few acceptance goldens which I regenerated against the latest source. Build, unit tests, and the auth acceptance suite all pass locally.

Diff against main: 7 files, +153/-39 — cmd/auth/token.go, cmd/root/auth.go, libs/auth/error.go + _test.go, plus the regenerated goldens and the changelog entry. The earlier behavioral concerns are addressed:

  • BuildLoginCommand no longer re-emits --workspace-id on the profile path (auth login --profile foo already picks up the stored value).
  • PAT and Basic reauth suggestions in writeReauthSteps now shell-quote profile names too.

Ready for a re-review whenever you have a moment.

(comment posted by Claude)

jamesbroadhead and others added 4 commits May 26, 2026 08:57
Reformats the `auth token` error so the suggested `databricks auth login`
command lands on its own line with blank-line padding above and below,
making it easy to select and copy. Also pulls every render path through
the new `BuildLoginCommand` helper so they all benefit from shell-quoting
and consistent --workspace-id emission.

Rebased onto current main; addresses simonfaltum's May 7 review:

- **Blocking fix**: `writeReauthSteps`'s `AuthTypeDatabricksCli` profile branch
  now routes through `BuildLoginCommand(ctx, cfg.Profile, cfg.WorkspaceID, nil)`
  instead of the raw `fmt.Fprintf(... "--profile %s", ...)`. Previously this
  branch (the most common 401 path) missed both shell-quoting and
  --workspace-id; on unified/SPOG hosts the suggested command could target
  the wrong workspace.
- Changelog link points at #5115 (was the superseded #4602).
- `RewriteAuthError` unified on the blank-line-padded layout to match
  `helpfulError`. Acceptance test golden file regenerated.
- `BuildLoginCommand` doc-comment expanded with two clarifications:
  (a) why the profile path re-emits --workspace-id (pin to the workspace
  the failing call resolved against, even if the profile's persisted
  value drifted), and (b) why Account/Workspace OAuth cases drop
  workspaceID (account args target the account API; workspace args
  already identify a workspace by host).
- Two new test cases on `TestBuildLoginCommand_AppendsWorkspaceID`:
  negative assertions that `WorkspaceOAuthArgument` and
  `AccountOAuthArgument` paths omit `--workspace-id` even when provided,
  plus a shell-quoting case (`profile = "weird name"`).

Co-authored-by: Isaac
databricks auth login --profile foo already picks up the profile's
stored workspace_id, so re-emitting --workspace-id is redundant noise
left over from an earlier iteration. Drop it from BuildLoginCommand's
profile branch and from writeReauthSteps' AuthTypeDatabricksCli
profile case, and refresh the affected acceptance goldens.

Co-authored-by: Isaac
The Pat and Basic branches of writeReauthSteps still emitted
'databricks auth login --profile <raw>' via fmt.Fprintf, so a profile
name with spaces or shell metacharacters produced an unsafe
copy-paste. Route them through BuildLoginCommand so they inherit the
same shell-quoting the DatabricksCli branch already gets, and add a
regression test using a profile name with a space.

Co-authored-by: Isaac
- RewriteAuthError now threads DiscoveryURL through to ToOAuthArgument
  so unified/SPOG hosts are recognized and the suggested reauth command
  emits --account-id and --workspace-id correctly. Without it, hosts
  that needed unified treatment were being misclassified by host-shape
  heuristics alone. Updated both callers (cmd/auth/token.go,
  cmd/root/auth.go) to pass the field from their context (authArguments
  / cfg).
- TestBuildLoginCommand_AppendsWorkspaceID now uses .test TLD fixtures
  with explicit DiscoveryURL so ToOAuthArgument never falls through to
  a real .well-known resolution (PR #5125 convention — public hosts
  can stall CI ~5min per call on networks that can't fast-fail).

Co-authored-by: Isaac
@jamesbroadhead jamesbroadhead force-pushed the fix-auth-login-error-formatting branch from de2ac0d to 4889f4b Compare May 26, 2026 08:59
@jamesbroadhead

Copy link
Copy Markdown
Contributor Author

👋 @simonfaltum @andrewnester — Claude here on James's behalf.

Rebased onto current main (was BEHIND), pushed 4889f4bfb. No code changes vs. the prior push — just a clean rebase over the 3 master commits that landed since the last force-push (postgres / testserver / pydabs/linguist fixes). Build, ./libs/auth/..., ./cmd/auth/... unit tests, and the TestAccept/cmd/auth/token acceptance suite all pass locally.

Replied inline to each of your outstanding May 7 comments — every point is addressed in the current diff:

  • NEXT_CHANGELOG.md link → #5115 (was #4602)
  • RewriteAuthError unified on the blank-line-padded layout; force-refresh-invalid-refresh-token golden + cmd/auth/token_test.go regenerated
  • DatabricksCli/Pat/Basic profile branches in writeReauthSteps all route through BuildLoginCommand (shell-quoting included)
  • BuildLoginCommand doc-comment now documents both the profile-path and Account/Workspace OAuth workspaceID omissions
  • TestBuildLoginCommand_AppendsWorkspaceID has negative assertions on both single-host paths plus a "weird name" shell-quoting case
  • --workspace-id dropped from the profile path (per our thread)

Diff against main: 7 files, +164/-39. Ready for a re-review whenever you have a moment.

(comment posted by Claude)

@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Commit: 4889f4b

Run: 26442736862

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.

3 participants