charmbracelet/crush · error

failed to get agent status: %w

Error message

failed to get agent status: %w

What it means

GetAgentInfo GETs /workspaces/{id}/agent and wraps any c.get transport error with 'failed to get agent status'. This is the connectivity/path failure case; the original error is wrapped and retrievable. waitForAgent callers see this on every failed poll attempt.

Source

Thrown at internal/client/proto.go:460

// ClearAgentSessionQueuedPrompts clears the queued prompts for a session.
func (c *Client) ClearAgentSessionQueuedPrompts(ctx context.Context, id string, sessionID string) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent/sessions/%s/prompts/clear", id, sessionID), nil, nil, nil)
	if err != nil {
		return fmt.Errorf("failed to clear session agent queued prompts: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return fmt.Errorf("failed to clear session agent queued prompts: status code %d", rsp.StatusCode)
	}
	return nil
}

// GetAgentInfo retrieves the agent status for a workspace.
func (c *Client) GetAgentInfo(ctx context.Context, id string) (*proto.AgentInfo, error) {
	rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/agent", id), nil, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to get agent status: %w", err)
	}
	defer rsp.Body.Close()
	if err := checkStatus(rsp); err != nil {
		return nil, fmt.Errorf("failed to get agent status: %w", err)
	}
	var info proto.AgentInfo
	if err := json.NewDecoder(rsp.Body).Decode(&info); err != nil {
		return nil, fmt.Errorf("failed to decode agent status: %w", err)
	}
	return &info, nil
}

// UpdateAgent triggers an agent model update on the server.
func (c *Client) UpdateAgent(ctx context.Context, id string) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent/update", id), nil, nil, nil)
	if err != nil {
		return fmt.Errorf("failed to update agent: %w", err)
	}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Wait and retry — during waitForAgent this is usually transient startup
  2. Confirm the server address/port configuration
  3. Check the workspace ID is correct
  4. Inspect the wrapped cause for the specific transport error

Example fix

// before
info, err := client.GetAgentInfo(ctx, wsID)
// after
info, err := client.GetAgentInfo(ctx, wsID)
if err != nil {
	if ctx.Err() != nil { return nil, ctx.Err() }
	time.Sleep(pollInterval) // transient during waitForAgent
}
Defensive patterns

Strategy: retry

Validate before calling

if wsID == "" { return errors.New("workspace ID required for GetAgentInfo") }
if err := ctx.Err(); err != nil { return err }

Type guard

func isAgentPollTransient(err error) bool {
	var ne net.Error
	return errors.As(err, &ne) || errors.Is(err, context.DeadlineExceeded)
}

Try / catch

info, err := client.GetAgentInfo(ctx, wsID)
if err != nil {
	if isAgentPollTransient(err) && attempts < maxAttempts {
		time.Sleep(pollInterval)
		continue
	}
	return nil, err
}

Prevention

When it happens

Trigger: Calling GetAgentInfo when the server is down, the workspace ID is invalid, DNS/proxy fails, or the context is canceled while polling for agent readiness.

Common situations: waitForAgent retry loop during server startup when the endpoint is not yet listening; wrong port in client config; network flake.

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/1c9990d9bc97ea23. Report an issue: GitHub.