From 5f790eab1f0a55f2c4173ecb74c4b3223b627f3a Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Wed, 21 Oct 2026 20:32:15 -0700 Subject: [PATCH] fix(lk): say why no user resolves: the default user, or several users When no user could act on the target Public API, resolveSessionUser always said "no user is signed in", even when the default user was signed in elsewhere or two users were signed in there. It now says which: - two or more users on that API and none is the default: pass --user to pick one; - the default user is signed in to another API: names it and that API; - the default user isn't signed in anywhere: names it. "No user is signed in" is left for when that's true. An explicit --user already has its own errors and is unaffected. --- cmd/lk/testdata/script/broken-default-user.txtar | 13 ++++--------- cmd/lk/testdata/script/two-users-same-api.txtar | 3 +-- cmd/lk/user_auth.go | 16 +++++++++++++++- cmd/lk/user_auth_test.go | 4 ++++ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/cmd/lk/testdata/script/broken-default-user.txtar b/cmd/lk/testdata/script/broken-default-user.txtar index 5d30f5da..c84d63bb 100644 --- a/cmd/lk/testdata/script/broken-default-user.txtar +++ b/cmd/lk/testdata/script/broken-default-user.txtar @@ -1,17 +1,12 @@ -# A default user that no longer resolves is a clear error with the way to fix -# it, never a crash. Today the error says nobody is signed in to the default -# Public API, while another user is signed in elsewhere and the real problem -# is the default user. +# A default user that no longer resolves is a clear error that names it and +# says how to fix it, never a crash, even with another user signed in +# elsewhere. ! exec lk --user-auth project list ! stdout . -stderr 'run `lk cloud auth --user-auth` to sign in' -cp stderr lk.stderr +stderr '^the default user "gone@example.com" is not signed in to https://beta-api.livekit.cloud \(run `lk cloud auth --user-auth` to sign in\)$' requests ! stdout . -skip 'known bug: the error doesn''t say the default user no longer resolves' -grep 'gone@example.com' lk.stderr - -- home/.livekit/cli-config.yaml -- default_user: gone@example.com users: diff --git a/cmd/lk/testdata/script/two-users-same-api.txtar b/cmd/lk/testdata/script/two-users-same-api.txtar index 3e6abb45..51c93c36 100644 --- a/cmd/lk/testdata/script/two-users-same-api.txtar +++ b/cmd/lk/testdata/script/two-users-same-api.txtar @@ -15,8 +15,7 @@ exec lk --user-auth --user ops@example.com project list requests cmp stdout want-requests -skip 'known bug: with two users signed in, the error says no user is signed in instead of asking for --user' -grep 'pass --user' refused.stderr +grep '^2 users are signed in to http://publicapi.test and none is the default user; pass --user to pick one$' refused.stderr -- home/.livekit/cli-config.yaml -- users: diff --git a/cmd/lk/user_auth.go b/cmd/lk/user_auth.go index c8ea9821..4a4d660e 100644 --- a/cmd/lk/user_auth.go +++ b/cmd/lk/user_auth.go @@ -312,9 +312,23 @@ func resolveSessionUser(conf *config.CLIConfig, userRef string, apiURLSet bool) return nil, fmt.Errorf("user %q is not signed in to %s (run %s to sign in)", userRef, publicAPIURL, signInCommand()) } } - if users := conf.UsersForAPIURL(publicAPIURL); len(users) == 1 { + users := conf.UsersForAPIURL(publicAPIURL) + if len(users) == 1 { return users[0], nil } + // Here userRef, if set, is the default user: an explicit --user returned + // above. + switch { + case len(users) > 1: + return nil, fmt.Errorf("%d users are signed in to %s and none is the default user; pass --user to pick one", + len(users), publicAPIURL) + case userRef != "": + if elsewhere := conf.FindUsers(userRef); len(elsewhere) > 0 { + return nil, fmt.Errorf("the default user %q is signed in to %s, not %s (run %s to sign in there)", + userRef, cmp.Or(elsewhere[0].APIURL, public.DefaultBaseURL), publicAPIURL, signInCommand()) + } + return nil, fmt.Errorf("the default user %q is not signed in to %s (run %s to sign in)", userRef, publicAPIURL, signInCommand()) + } return nil, fmt.Errorf("no user is signed in to %s (run %s to sign in)", publicAPIURL, signInCommand()) } diff --git a/cmd/lk/user_auth_test.go b/cmd/lk/user_auth_test.go index 164e83ef..47da0d84 100644 --- a/cmd/lk/user_auth_test.go +++ b/cmd/lk/user_auth_test.go @@ -168,6 +168,10 @@ func TestRequireUserSessionAPIURL(t *testing.T) { token, _, err = resolve(t, "--experimental-api-url", public.DefaultBaseURL) require.NoError(t, err) assert.Equal(t, "prod", token, "the old --experimental-api-url spelling still sets the URL") + + _, _, err = resolve(t, "--public-api-url", "https://other.example") + assert.ErrorContains(t, err, `the default user "usr_stg" is signed in to `+staging+`, not https://other.example`, + "an API nobody is signed in to names where the default user is") }) t.Run("--user", func(t *testing.T) {