charmbracelet/crush · error

failed to create request: %w

Error message

failed to create request: %w

What it means

http.NewRequestWithContext failed while constructing the GET request for the download URL. This happens before any network I/O and indicates the URL could not be parsed by net/url (control characters, invalid scheme handling after the earlier prefix check, etc.).

Source

Thrown at internal/agent/tools/download.go:122

			if !p {
				return NewPermissionDeniedResponse(), nil
			}

			// Handle timeout with context
			requestCtx := ctx
			if params.Timeout > 0 {
				maxTimeout := 600 // 10 minutes
				if params.Timeout > maxTimeout {
					params.Timeout = maxTimeout
				}
				var cancel context.CancelFunc
				requestCtx, cancel = context.WithTimeout(ctx, time.Duration(params.Timeout)*time.Second)
				defer cancel()
			}

			req, err := http.NewRequestWithContext(requestCtx, "GET", params.URL, nil)
			if err != nil {
				return fantasy.ToolResponse{}, fmt.Errorf("failed to create request: %w", err)
			}

			req.Header.Set("User-Agent", "crush/1.0")

			resp, err := client.Do(req)
			if err != nil {
				return fantasy.ToolResponse{}, fmt.Errorf("failed to download from URL: %w", err)
			}
			defer resp.Body.Close()

			if resp.StatusCode != http.StatusOK {
				return fantasy.NewTextErrorResponse(fmt.Sprintf("Request failed with status code: %d", resp.StatusCode)), nil
			}

			// Create parent directories if they don't exist
			if err := os.MkdirAll(filepath.Dir(filePath), 0o755); err != nil {
				return fantasy.ToolResponse{}, fmt.Errorf("failed to create parent directories: %w", err)
			}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. URL-encode the address (url.PathEscape segments or use url.Parse to validate) before calling
  2. Strip whitespace/control characters from the URL
  3. Check the wrapped %w error for the exact parse failure and offending string

Example fix

// before
url := "https://example.com/my file.zip"
// after
url := "https://example.com/my%20file.zip"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(strings.TrimSpace(rawURL))
if err != nil || u.Scheme == "" || u.Host == "" {
    return nil, fmt.Errorf("invalid download URL: %q", rawURL)
}

Try / catch

req, err := http.NewRequestWithContext(ctx, "GET", rawURL, nil)
if err != nil {
    var urlErr *url.Error
    if errors.As(err, &urlErr) {
        return nil, fmt.Errorf("bad URL %q: %v", rawURL, urlErr.Err)
    }
    return err
}

Prevention

When it happens

Trigger: params.URL contains characters invalid in a URL (raw spaces, control characters, unparseable host), producing a *url.Error from url.Parse inside http.NewRequestWithContext.

Common situations: LLM passes a URL with unencoded spaces or backslashes; copy-pasted URLs with trailing control characters; malformed IPv6 literals or ports; URLs built by string concatenation.

Related errors


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