mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(cli): error when CODER_SESSION_TOKEN env var is set during login (#22879)
_Disclaimer: created with Opus 4.6 and Coder Agents._
## Problem
When `CODER_SESSION_TOKEN` is set as an environment variable with an
invalid value, `coder login` fails with a confusing error:
```
error: Trace=[create api key: ]
You are signed out or your session has expired. Please sign in again to continue.
Suggestion: Try logging in using 'coder login'.
```
The suggestion to run `coder login` is what the user just did, making it
circular and unhelpful.
## Root cause
The `--token` flag is mapped to `CODER_SESSION_TOKEN` via serpent. When
the env var is set, `coder login` picks it up as the session token and
tries to use it to create a new API key, which fails because the token
is invalid. Even if login were to succeed and write a new token to disk,
subsequent commands would still use the env var (which takes precedence
over the on-disk token), so the user would remain stuck.
## Fix
Before attempting login, check if `CODER_SESSION_TOKEN` is set in the
environment. If so, return a clear error telling the user to unset it:
```
the environment variable CODER_SESSION_TOKEN is set, which takes precedence
over the session token stored on disk. Please unset it and try again.
unset CODER_SESSION_TOKEN
```
## Testing
Added `TestLogin/SessionTokenEnvVar` that verifies the error is returned
when the env var is set.
This commit is contained in:
@@ -356,6 +356,20 @@ func (r *RootCmd) login() *serpent.Command {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If CODER_SESSION_TOKEN is set in the environment, abort login.
|
||||
// The env var takes precedence over a token stored on disk, so
|
||||
// even if we complete login and write a new token to the session
|
||||
// file, subsequent CLI commands would still use the environment
|
||||
// variable value.
|
||||
if inv.Environ.Get(envSessionToken) != "" {
|
||||
return xerrors.Errorf(
|
||||
"%s is set. This environment variable takes precedence over any session token stored on disk.\n\n"+
|
||||
"To log in, unset the environment variable and re-run this command:\n\n"+
|
||||
"\tunset %s",
|
||||
envSessionToken, envSessionToken,
|
||||
)
|
||||
}
|
||||
|
||||
sessionToken, _ := inv.ParsedFlags().GetString(varToken)
|
||||
if sessionToken == "" {
|
||||
authURL := *serverURL
|
||||
|
||||
@@ -516,6 +516,18 @@ func TestLogin(t *testing.T) {
|
||||
require.NotEqual(t, client.SessionToken(), sessionFile)
|
||||
})
|
||||
|
||||
t.Run("SessionTokenEnvVar", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
coderdtest.CreateFirstUser(t, client)
|
||||
root, _ := clitest.New(t, "login", client.URL.String())
|
||||
root.Environ.Set("CODER_SESSION_TOKEN", "invalid-token")
|
||||
err := root.Run()
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "CODER_SESSION_TOKEN is set")
|
||||
require.Contains(t, err.Error(), "unset CODER_SESSION_TOKEN")
|
||||
})
|
||||
|
||||
t.Run("KeepOrganizationContext", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
|
||||
Reference in New Issue
Block a user