charmbracelet/crush · error

invalid response format: missing results field

Error message

invalid response format: missing results field

What it means

Raised by sourcegraphSearchResults when search["results"] is missing or not a map (internal/agent/tools/sourcegraph.go:219-222). In a healthy response, data.search.results holds matchCount and the results array. Missing results usually means Sourcegraph returned a Search connection with alert/limitHit state instead, or a GraphQL error degraded the response while still yielding a data.search object.

Source

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

		}
	}
	return true
}

func sourcegraphSearchResults(result map[string]any) (map[string]any, error) {
	data, ok := result["data"].(map[string]any)
	if !ok {
		return nil, fmt.Errorf("invalid response format: missing data field")
	}

	search, ok := data["search"].(map[string]any)
	if !ok {
		return nil, fmt.Errorf("invalid response format: missing search field")
	}

	searchResults, ok := search["results"].(map[string]any)
	if !ok {
		return nil, fmt.Errorf("invalid response format: missing results field")
	}
	return searchResults, nil
}

func writeSourcegraphHeader(buffer *strings.Builder, searchResults map[string]any) {
	matchCount, _ := searchResults["matchCount"].(float64)
	resultCount, _ := searchResults["resultCount"].(float64)
	limitHit, _ := searchResults["limitHit"].(bool)

	buffer.WriteString("# Sourcegraph Search Results\n\n")
	fmt.Fprintf(buffer, "Found %d matches across %d results\n", int(matchCount), int(resultCount))

	if limitHit {
		buffer.WriteString("(Result limit reached, try a more specific query)\n")
	}

	buffer.WriteString("\n")
}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Inspect the raw response for a data.search.alert field — add a repo: filter or narrower pattern to satisfy Sourcegraph's search limits.
  2. Retry with a more specific query (scope by repo:, file:, or lang:) to avoid server-side search alerts and timeouts.
  3. Log the JSON body to confirm the envelope shape and detect any schema drift requiring a query-string update in the tool.
  4. If self-hosted, align the instance's Sourcegraph version with the API version the query string assumes.

Example fix

// before
params := SourcegraphParams{Query: "TODO"}

// after
params := SourcegraphParams{Query: "TODO repo:github.com/charmbracelet/crush", Count: 10}
Defensive patterns

Strategy: type-guard

Validate before calling

results, ok := search["results"].(map[string]any)
if !ok {
    if alert, ok := search["alert"].(map[string]any); ok {
        return fmt.Errorf("sourcegraph alert: %v", alert["title"])
    }
}

Type guard

func extractSearchResults(search map[string]any) (map[string]any, bool) {
    results, ok := search["results"].(map[string]any)
    return results, ok
}

Try / catch

formatted, err := formatSourcegraphResults(result, ctxWindow, count)
if err != nil {
    return fantasy.NewTextErrorResponse("Failed to format results: " + err.Error() + "; try a narrower query with repo: filter"), nil
}

Prevention

When it happens

Trigger: formatSourcegraphResults -> sourcegraphSearchResults sees data.search without a "results" map: the query triggered a search alert (e.g. pattern matches too many repos, needs a repo: or global limit filter) so Sourcegraph omits results, a timeout field replaced results (timedout/missing), or a schema change to the results connection.

Common situations: Broad searches without a repo: filter hitting Sourcegraph's 'too many repositories' alert; queries against sourcegraph.com that exceed public search limits; older Sourcegraph instances whose schema predates the current results shape; queries that time out server-side returning degraded envelopes.

Related errors


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