# auth: name the core in the refresh re-login hint

`d465218`→[main](/content/gh/entireio/cli/commits/main/index.html)·  
  
toothbrush·1mo ago·2 files·+13 added/-3 removed

When a refresh fails (expired/revoked family, or no refresh token), the  
error now points at the specific core — `ENTIRE_AUTH_BASE_URL=<core> entire login` — so a multi-core user re-authenticates against the right one. Matches clusterdiscovery.RenderLoginHint's idiom.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

## Sessions

22da7112c436View transcript

## Changes

2

- cmd/entire/cli/auth  
  
  - Mrefresh.go+6/-2  
  - Mrefresh_test.go+7/-1

```
131 unmodified lines

132
133
134
135
136
137
138
139
140
141
142
139
143
144
141
145
146
147
148

131 unmodified lines

return nil, fmt.Errorf("init token manager for context %q: %w", c.Name, err)
}
name := c.Name
coreURL := strings.TrimRight(c.CoreURL, "/")
// Name the core in the re-login hint so a multi-core user logs back
// into the right one; matches clusterdiscovery.RenderLoginHint's idiom.
relogin := fmt.Sprintf("ENTIRE_AUTH_BASE_URL=%%s entire login", coreURL)
return func(ctx context.Context) (string, error) {
    tok, err := mgr.Refresh(ctx)
    switch {
    case errors.Is(err, tokenmanager.ErrReauthRequired):
        return "", fmt.Errorf("login session for %q expired; run `entire login` to re-authenticate", name)
        return "", fmt.Errorf("login session for %q (%s) expired; run `%%s` to re-authenticate", name, coreURL, relogin)
    case errors.Is(err, tokenmanager.ErrNotLoggedIn):
        return "", fmt.Errorf("no usable login for %q; run `entire login`", name)
        return "", fmt.Errorf("no usable login for %q (%s); run `%%s`", name, coreURL, relogin)
    case err != nil:
        return "", fmt.Errorf("refresh login token: %%w", err)
    }
}
```

Mcmd/entire/cli/auth/refresh.go+6/-2

```
6 unmodified lines

7
8
9
10
11
12
13
98 unmodified lines

112
113
114
114
115
116
117
118
119
120
121
122
123
124
125

6 unmodified lines

"net/http"
    "net/http/httptest"
    "path/filepath"
    "strings"
    "testing"
    "time"

98 unmodified lines

if err != nil {
        t.Fatalf("NewRefreshingLoginProvider: %%v", err)
    }
    if _, err := provider(context.Background()); err == nil {
    _, err = provider(context.Background())
    if err == nil {
        t.Fatal("expired token with no refresh: want a re-login error")
    }
    // The hint must name the core so a multi-core user re-logs into the right one.
    if got := err.Error(); !strings.Contains(got, "https://core.example") || !strings.Contains(got, "entire login") {
        t.Fatalf("re-login error = %%q, want it to name the core and the login command", got)
    }
}

// The full path: an expired access token is silently re-minted from the
```

Mcmd/entire/cli/auth/refresh_test.go+7/-1
