wavetermdev/waveterm · error

request failed: %w

Error message

request failed: %w

What it means

After building the chat request, the HTTP client.Do call failed (DNS failure, connection refused, TLS error, timeout, proxy failure); RunChatStep wraps the transport error with 'request failed:' since no HTTP response was obtained at all.

Source

Thrown at pkg/aiusechat/openaichat/openaichat-backend.go:70

		chatMsg, ok := genMsg.(*StoredChatMessage)
		if !ok {
			return nil, nil, nil, fmt.Errorf("expected StoredChatMessage, got %T", genMsg)
		}
		messages = append(messages, *chatMsg.Message.clean())
	}

	req, err := buildChatHTTPRequest(ctx, messages, chatOpts)
	if err != nil {
		return nil, nil, nil, err
	}

	client, err := aiutil.MakeHTTPClient(chatOpts.Config.ProxyURL)
	if err != nil {
		return nil, nil, nil, err
	}
	resp, err := client.Do(req)
	if err != nil {
		return nil, nil, nil, fmt.Errorf("request failed: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		bodyBytes, _ := io.ReadAll(resp.Body)
		return nil, nil, nil, fmt.Errorf("API returned status %d: %s", resp.StatusCode, string(bodyBytes))
	}

	// Setup SSE if this is a new request (not a continuation)
	if cont == nil {
		if err := sseHandler.SetupSSE(); err != nil {
			return nil, nil, nil, fmt.Errorf("failed to setup SSE: %w", err)
		}
	}

	// Stream processing
	stopReason, assistantMsg, err := processChatStream(ctx, resp.Body, sseHandler, chatOpts, cont)
	if err != nil {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the wrapped error (%w chain) for the root cause (timeout vs DNS vs refused)
  2. Verify network connectivity and the configured API endpoint URL
  3. Check/clear Config.ProxyURL if a proxy is not intended or is misconfigured
  4. Increase Config.TimeoutMs or the context deadline for long completions
  5. Retry with backoff on transient transport failures

Example fix

// before
resp, err := client.Do(req)
if err != nil { return fmt.Errorf("request failed: %w", err) }
// after
resp, err := client.Do(req)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        return fmt.Errorf("request timed out (increase TimeoutMs): %w", err)
    }
    return retryable(fmt.Errorf("request failed: %w", err))
}
Defensive patterns

Strategy: retry

Validate before calling

if chatOpts.Config.ProxyURL != "" {
    if u, err := url.Parse(chatOpts.Config.ProxyURL); err != nil || u.Host == "" {
        return fmt.Errorf("bad proxy URL: %v", err)
    }
}

Try / catch

resp, err := client.Do(req)
if err != nil {
    var nerr net.Error
    if errors.As(err, &nerr) && nerr.Timeout() { /* retry with backoff */ }
    if errors.Is(err, context.DeadlineExceeded) { /* raise TimeoutMs */ }
    return fmt.Errorf("request failed: %w", err)
}

Prevention

When it happens

Trigger: client.Do returns an error: network unreachable, proxy misconfigured (chatOpts.Config.ProxyURL), request context cancelled/timed out (including Config.TimeoutMs), or TLS handshake failure against the chat API endpoint.

Common situations: No internet or firewall blocking the endpoint; bad ProxyURL in Config; TimeoutMs too small for slow LLM responses; wrong API base URL; server outage.

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 wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/1d271c24aa8f1187. Report an issue: GitHub.