charmbracelet/crush · error
failed to get session agent info: %w
Error message
failed to get session agent info: %w
What it means
GetAgentSessionInfo GETs /workspaces/{id}/agent/sessions/{sid} and returns *proto.AgentSession. This error wraps a transport failure from c.get (server unreachable, connection refused/reset, timeout, malformed URL from bad ids) before the response is examined, with the cause preserved via %w.
Source
Thrown at internal/client/proto.go:550
if err != nil {
return proto.ShellCommandResponse{}, fmt.Errorf("failed to run shell command: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return proto.ShellCommandResponse{}, fmt.Errorf("failed to run shell command: status code %d", rsp.StatusCode)
}
var resp proto.ShellCommandResponse
if err := json.NewDecoder(rsp.Body).Decode(&resp); err != nil {
return proto.ShellCommandResponse{}, fmt.Errorf("failed to decode shell command response: %w", err)
}
return resp, nil
}
// GetAgentSessionInfo retrieves the agent session info for a workspace.
func (c *Client) GetAgentSessionInfo(ctx context.Context, id string, sessionID string) (*proto.AgentSession, error) {
rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/agent/sessions/%s", id, sessionID), nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to get session agent info: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to get session agent info: status code %d", rsp.StatusCode)
}
var info proto.AgentSession
if err := json.NewDecoder(rsp.Body).Decode(&info); err != nil {
return nil, fmt.Errorf("failed to decode session agent info: %w", err)
}
return &info, nil
}
// AgentSummarizeSession requests a session summarization.
func (c *Client) AgentSummarizeSession(ctx context.Context, id string, sessionID string) error {
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent/sessions/%s/summarize", id, sessionID), nil, nil, nil)
if err != nil {
return fmt.Errorf("failed to summarize session: %w", err)
}View on GitHub (pinned to 7944b8e522)
Solutions
- Confirm the server is running and reachable at the configured base URL.
- Validate id strings are non-empty and properly path-safe before building the request.
- Inspect the wrapped cause (%w) for the concrete transport failure.
- Add retry with backoff for transient connectivity blips in polling loops like AgentIsSessionBusy.
Example fix
// before: single-shot call inside a polling loop
busy, err := AgentIsSessionBusy(ctx, client, wsID, sid)
// after
info, err := client.GetAgentSessionInfo(ctx, wsID, sid)
if err != nil {
select {
case <-time.After(500 * time.Millisecond):
return AgentIsSessionBusy(ctx, client, wsID, sid) // bounded retry
case <-ctx.Done():
return ctx.Err()
}
} Defensive patterns
Strategy: retry
Validate before calling
// Go: validate IDs before building the request URL
if workspaceID == "" || sessionID == "" {
return fmt.Errorf("workspace and session ids required")
}
if strings.ContainsAny(workspaceID+sessionID, " /?#") {
return fmt.Errorf("ids must be URL-path safe")
} Type guard
// Go: separate transport errors from HTTP-status errors
func isTransportError(err error) bool {
return err != nil && !strings.Contains(err.Error(), "status code")
} Try / catch
info, err := client.GetAgentSessionInfo(ctx, wsID, sid)
for i := 0; err != nil && isTransportError(err) && i < 3; i++ {
select {
case <-time.After(time.Duration(250*(1<<i)) * time.Millisecond):
info, err = client.GetAgentSessionInfo(ctx, wsID, sid)
case <-ctx.Done():
return nil, ctx.Err()
}
}
if err != nil { return nil, err } Prevention
- Bound retries in polling loops with context cancellation.
- Smoke-test connectivity before polling bursts.
- Normalize/trim IDs at construction time to avoid malformed URLs.
- Distinguish transport from status errors before choosing to retry.
When it happens
Trigger: Calling GetAgentSessionInfo (e.g. from AgentIsSessionBusy) when the server is down, DNS fails, the connection times out, or the URL is malformed due to an invalid workspace/session id.
Common situations: Busy-check before sending a message while the server is restarting; whitespace or empty ids producing a bad URL; CI runners without network access to the server.
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
- failed to make request: %w
- failed to refresh OAuth token: %w
- failed to check project init: %w
- failed to mark project initialized: %w
- failed to get init prompt: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/14f5349a375f255f.
Report an issue: GitHub.