charmbracelet/crush · info

failed to create request: %w

Error message

failed to create request: %w

What it means

Wraps an http.NewRequestWithContext error when constructing the POST to https://sourcegraph.com/.api/graphql (internal/agent/tools/sourcegraph.go:110-118). This fires only for an invalid HTTP method, an unparseable URL, or a nil context/URL mismatch — none of which occur here since method, URL, and context are hardcoded/derived correctly. It is effectively a defensive branch.

Source

Thrown at internal/agent/tools/sourcegraph.go:117

			request := graphqlRequest{
				Query: "query Search($query: String!) { search(query: $query, version: V2, patternType: keyword ) { results { matchCount, limitHit, resultCount, approximateResultCount, missing { name }, timedout { name }, indexUnavailable, results { __typename, ... on FileMatch { repository { name }, file { path, url, content }, lineMatches { preview, lineNumber, offsetAndLengths } } } } } }",
			}
			request.Variables.Query = params.Query

			graphqlQueryBytes, err := json.Marshal(request)
			if err != nil {
				return fantasy.ToolResponse{}, fmt.Errorf("failed to marshal GraphQL request: %w", err)
			}
			graphqlQuery := string(graphqlQueryBytes)

			req, err := http.NewRequestWithContext(
				requestCtx,
				"POST",
				"https://sourcegraph.com/.api/graphql",
				bytes.NewBuffer([]byte(graphqlQuery)),
			)
			if err != nil {
				return fantasy.ToolResponse{}, fmt.Errorf("failed to create request: %w", err)
			}

			req.Header.Set("Content-Type", "application/json")
			req.Header.Set("User-Agent", "crush/1.0")

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

			if resp.StatusCode != http.StatusOK {
				body, _ := io.ReadAll(resp.Body)
				if len(body) > 0 {
					return fantasy.NewTextErrorResponse(fmt.Sprintf("Request failed with status code: %d, response: %s", resp.StatusCode, string(body))), nil
				}

				return fantasy.NewTextErrorResponse(fmt.Sprintf("Request failed with status code: %d", resp.StatusCode)), nil

View on GitHub (pinned to 7944b8e522)

Solutions

  1. No user action needed; treat as a bug report trigger if ever observed.
  2. If self-hosting a modified build with a custom endpoint, validate the endpoint URL parses (url.Parse) at startup.

Example fix

// before (if endpoint becomes configurable)
req, err := http.NewRequestWithContext(requestCtx, "POST", endpoint, body)

// after
u, perr := url.Parse(endpoint)
if perr != nil || u.Scheme == "" || u.Host == "" {
    return fantasy.ToolResponse{}, fmt.Errorf("invalid sourcegraph endpoint: %q", endpoint)
}
req, err := http.NewRequestWithContext(requestCtx, "POST", endpoint, body)
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, body)
if err != nil {
    return fmt.Errorf("failed to create request: %w", err)
}

Prevention

When it happens

Trigger: http.NewRequestWithContext returns an error — requires an invalid context (nil), a malformed URL, or an invalid method; with the hardcoded "POST" and fixed URL this is unreachable in normal operation.

Common situations: Essentially never hit by users; could only appear if the source were modified to use a configurable endpoint with a malformed URL string (e.g. missing scheme, control characters).

Related errors


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