plandex-ai/plandex · error
error fetching users: %s
Error message
error fetching users: %s
What it means
This error wraps a failure from api.Client.ListUsers() when the CLI fetches the organization's user list in a background goroutine. The client returns *shared.ApiError, and its Msg field is interpolated into 'error fetching users: %s'. It signals the API call for listing users failed (network, auth, or server-side), so the revoke command aborts before it can present users for selection.
Source
Thrown at app/cli/cmd/revoke.go:43
func revoke(cmd *cobra.Command, args []string) {
auth.MustResolveAuthWithOrg()
email := ""
if len(args) > 0 {
email = args[0]
}
var userResp *shared.ListUsersResponse
var pendingInvites []*shared.Invite
errCh := make(chan error)
term.StartSpinner("")
go func() {
var err *shared.ApiError
userResp, err = api.Client.ListUsers()
if err != nil {
errCh <- fmt.Errorf("error fetching users: %s", err.Msg)
return
}
errCh <- nil
}()
go func() {
var err *shared.ApiError
pendingInvites, err = api.Client.ListPendingInvites()
if err != nil {
errCh <- fmt.Errorf("error fetching pending invites: %s", err.Msg)
return
}
errCh <- nil
}()
for i := 0; i < 2; i++ {
err := <-errCh
if err != nil {View on GitHub (pinned to e2d772072e)
Solutions
- Run the auth/login flow again to refresh the API key or session token
- Verify network connectivity and proxy settings can reach the API host
- Confirm the CLI is pointed at the correct org and the account has member-list permissions
- Check the underlying err.Msg printed in the message for the exact HTTP status and act on it
Example fix
// before
errCh <- fmt.Errorf("error fetching users: %s", err.Msg)
// after
if err.Status == 401 {
errCh <- fmt.Errorf("error fetching users: %s (run `auth login` to refresh credentials)", err.Msg)
} else {
errCh <- fmt.Errorf("error fetching users: %s", err.Msg)
} Defensive patterns
Strategy: type-guard
Validate before calling
// pre-flight: ensure credentials and connectivity before invoking the command
if api.Client == nil || api.Client.APIKey == "" {
return fmt.Errorf("not authenticated: run the login command first")
}
if err := api.Client.Ping(); err != nil {
return fmt.Errorf("API unreachable: %w", err)
} Type guard
func isApiError(err error) (*shared.ApiError, bool) {
if ae, ok := err.(*shared.ApiError); ok {
return ae, true
}
return nil, false
} Try / catch
userResp, err := api.Client.ListUsers()
var apiErr *shared.ApiError
if err != nil {
if ae, ok := err.(*shared.ApiError); ok { apiErr = ae }
if apiErr != nil && apiErr.Status == 401 {
return reauthAndRetry()
}
return fmt.Errorf("error fetching users: %w", err)
} Prevention
- Run the login/auth command before org commands and refresh tokens on a schedule
- Check err.Msg/status codes and handle 401 with automatic re-auth
- Verify network/proxy access to the API host in CI environments
- Fail fast with a clear message when the client is unauthenticated
When it happens
Trigger: Calling the revoke command while ListUsers() returns a non-nil *shared.ApiError: invalid or expired API key, network outage, org ID not set, or the API returning 4xx/5xx. The goroutine sends the wrapped error to errCh and the command exits.
Common situations: Expired session token after a long-lived CLI session; running the command without being logged in; corporate proxy blocking the API host; user lacking permissions to list org members.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- error listing contexts: %v
- error getting context body: %v
- error fetching pending invites: %s
- error getting custom model packs: %v
- error getting default config: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/1dbea116099ceea6.
Report an issue: GitHub.