charmbracelet/crush · error

failed to get permissions skip requests: %w

Error message

failed to get permissions skip requests: %w

What it means

GetPermissionsSkipRequests wraps any transport-level failure of the GET request to /workspaces/{id}/permissions/skip with this message. It only fires when c.get itself returns an error (connection refused, context canceled, invalid URL, etc.) — non-200 responses produce the separate 'status code %d' variant. The underlying cause is preserved via %w.

Source

Thrown at internal/client/proto.go:751

// SetPermissionsSkipRequests sets the skip-requests flag for a workspace.
func (c *Client) SetPermissionsSkipRequests(ctx context.Context, id string, skip bool) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/permissions/skip", id), nil, jsonBody(proto.PermissionSkipRequest{Skip: skip}), http.Header{"Content-Type": []string{"application/json"}})
	if err != nil {
		return fmt.Errorf("failed to set permissions skip requests: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return fmt.Errorf("failed to set permissions skip requests: status code %d", rsp.StatusCode)
	}
	return nil
}

// GetPermissionsSkipRequests retrieves the skip-requests flag for a workspace.
func (c *Client) GetPermissionsSkipRequests(ctx context.Context, id string) (bool, error) {
	rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/permissions/skip", id), nil, nil)
	if err != nil {
		return false, fmt.Errorf("failed to get permissions skip requests: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return false, fmt.Errorf("failed to get permissions skip requests: status code %d", rsp.StatusCode)
	}
	var skip proto.PermissionSkipRequest
	if err := json.NewDecoder(rsp.Body).Decode(&skip); err != nil {
		return false, fmt.Errorf("failed to decode permissions skip requests: %w", err)
	}
	return skip.Skip, nil
}

// GetConfig retrieves the workspace-specific configuration.
func (c *Client) GetConfig(ctx context.Context, id string) (*config.Config, error) {
	rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/config", id), nil, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to get config: %w", err)
	}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Print/unwrap the wrapped cause (errors.Unwrap or %v of the error) to see the concrete transport failure.
  2. Verify the crush server/daemon is running and reachable at the configured address (curl the endpoint).
  3. Check ctx deadlines: pass context.WithTimeout with a generous timeout or ensure no premature cancelation.
  4. Sanitize/validate the workspace id before building the URL.

Example fix

// before
ctx := context.Background()
skip, err := c.GetPermissionsSkipRequests(ctx, wsID)
// after: bounded, inspectable request
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
skip, err := c.GetPermissionsSkipRequests(ctx, wsID)
if err != nil {
    log.Fatalf("get permissions skip failed: %+v", err) // shows wrapped cause
}
Defensive patterns

Strategy: retry

Validate before calling

// Go: probe the endpoint before the real call
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, baseURL+"/health", nil)
if _, err := http.DefaultClient.Do(req); err != nil {
    return fmt.Errorf("server not reachable: %w", err)
}

Try / catch

skip, err := c.GetPermissionsSkipRequests(ctx, id)
if err != nil {
    if errors.Is(ctx.Err(), context.DeadlineExceeded) {
        // increase timeout and retry
    }
    return fmt.Errorf("get permissions skip: %w", err)
}

Prevention

When it happens

Trigger: Calling GetPermissionsSkipRequests when the server is unreachable or the connection is refused, when ctx is canceled/times out before the request completes, or when the request URL is malformed (e.g. workspace id containing characters that break the URL).

Common situations: Dev server not started; wrong host/port configuration; VPN or proxy dropping the connection; context deadline exceeded during slow network; workspace id with spaces or slashes.

Related errors


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