charmbracelet/crush · error

failed to get MCP pending auth: %w

Error message

failed to get MCP pending auth: %w

What it means

MCPPendingAuth issues GET /workspaces/{id}/mcp/pending-auth to list MCP servers awaiting OAuth, and wraps any transport failure from c.get with this message. The request produced no HTTP response; the cause (connection refused, DNS, cancelation) is in the wrapped error.

Source

Thrown at internal/client/proto.go:336

		return nil, fmt.Errorf("failed to get MCP states: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to get MCP states: status code %d", rsp.StatusCode)
	}
	var states map[string]proto.MCPClientInfo
	if err := json.NewDecoder(rsp.Body).Decode(&states); err != nil {
		return nil, fmt.Errorf("failed to decode MCP states: %w", err)
	}
	return states, nil
}

// MCPPendingAuth retrieves the MCP servers awaiting OAuth authentication
// for a workspace.
func (c *Client) MCPPendingAuth(ctx context.Context, id string) ([]proto.MCPPendingAuthServer, error) {
	rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/mcp/pending-auth", id), nil, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to get MCP pending auth: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to get MCP pending auth: status code %d", rsp.StatusCode)
	}
	var pending []proto.MCPPendingAuthServer
	if err := json.NewDecoder(rsp.Body).Decode(&pending); err != nil {
		return nil, fmt.Errorf("failed to decode MCP pending auth: %w", err)
	}
	return pending, nil
}

// MCPAuthURL retrieves the current OAuth authorization URL for a named MCP
// server, if a flow is in progress.
func (c *Client) MCPAuthURL(ctx context.Context, id, name string) (string, error) {
	q := url.Values{"name": []string{name}}
	rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/mcp/auth-url", id), q, nil)
	if err != nil {

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Check the wrapped cause and restore connectivity (start/restart the crush server, fix the base URL).
  2. Confirm the server is listening and the workspace id is valid.
  3. Use context.WithTimeout with a reasonable budget and retry transient network errors with backoff.
  4. If polling, back off after repeated transport failures instead of hot-looping.

Example fix

// before
pending, err := client.MCPPendingAuth(ctx, wsID)
if err != nil { return err }
// after
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
pending, err := client.MCPPendingAuth(ctx, wsID)
if err != nil {
    if isNetError(err) { return retryWithBackoff(...); }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

if err := ctx.Err(); err != nil { return fmt.Errorf("context already done before MCPPendingAuth: %w", err) }
if wsID == "" { return errors.New("workspace id required") }

Type guard

func isContextErr(err error) bool {
	return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
}

Try / catch

pending, err := client.MCPPendingAuth(ctx, wsID)
if err != nil {
	if isContextErr(err) {
		return nil, fmt.Errorf("pending-auth poll canceled: %w", err) // caller may reschedule
	}
	return nil, fmt.Errorf("pending-auth unreachable: %w", err)
}

Prevention

When it happens

Trigger: Calling MCPPendingAuth(ctx, id) when the server is down or unreachable, the endpoint address is wrong, the connection drops, or ctx expires before the response arrives.

Common situations: Polling for pending OAuth servers after the daemon exited; DNS misconfiguration for a remote crush server; laptop resume killing keep-alive connections; short-lived context canceled by an outer timeout.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/ddf7f98edc55ee80. Report an issue: GitHub.