{"record":{"id":"af162aeb7fbda28e","repo":"charmbracelet/crush","slug":"invalid-response-format-missing-results-field","errorCode":null,"errorMessage":"invalid response format: missing results field","messagePattern":"invalid response format: missing results field","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/sourcegraph.go","lineNumber":221,"sourceCode":"\t\t}\n\t}\n\treturn true\n}\n\nfunc sourcegraphSearchResults(result map[string]any) (map[string]any, error) {\n\tdata, ok := result[\"data\"].(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid response format: missing data field\")\n\t}\n\n\tsearch, ok := data[\"search\"].(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid response format: missing search field\")\n\t}\n\n\tsearchResults, ok := search[\"results\"].(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid response format: missing results field\")\n\t}\n\treturn searchResults, nil\n}\n\nfunc writeSourcegraphHeader(buffer *strings.Builder, searchResults map[string]any) {\n\tmatchCount, _ := searchResults[\"matchCount\"].(float64)\n\tresultCount, _ := searchResults[\"resultCount\"].(float64)\n\tlimitHit, _ := searchResults[\"limitHit\"].(bool)\n\n\tbuffer.WriteString(\"# Sourcegraph Search Results\\n\\n\")\n\tfmt.Fprintf(buffer, \"Found %d matches across %d results\\n\", int(matchCount), int(resultCount))\n\n\tif limitHit {\n\t\tbuffer.WriteString(\"(Result limit reached, try a more specific query)\\n\")\n\t}\n\n\tbuffer.WriteString(\"\\n\")\n}","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/sourcegraph.go#L203-L239","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the raw response for a data.search.alert field — add a repo: filter or narrower pattern to satisfy Sourcegraph's search limits.","Retry with a more specific query (scope by repo:, file:, or lang:) to avoid server-side search alerts and timeouts.","Log the JSON body to confirm the envelope shape and detect any schema drift requiring a query-string update in the tool.","If self-hosted, align the instance's Sourcegraph version with the API version the query string assumes."],"exampleFix":"// before\nparams := SourcegraphParams{Query: \"TODO\"}\n\n// after\nparams := SourcegraphParams{Query: \"TODO repo:github.com/charmbracelet/crush\", Count: 10}","handlingStrategy":"type-guard","validationCode":"results, ok := search[\"results\"].(map[string]any)\nif !ok {\n    if alert, ok := search[\"alert\"].(map[string]any); ok {\n        return fmt.Errorf(\"sourcegraph alert: %v\", alert[\"title\"])\n    }\n}","typeGuard":"func extractSearchResults(search map[string]any) (map[string]any, bool) {\n    results, ok := search[\"results\"].(map[string]any)\n    return results, ok\n}","tryCatchPattern":"formatted, err := formatSourcegraphResults(result, ctxWindow, count)\nif err != nil {\n    return fantasy.NewTextErrorResponse(\"Failed to format results: \" + err.Error() + \"; try a narrower query with repo: filter\"), nil\n}","preventionTips":["Always include a repo: or org: filter to avoid Sourcegraph's too-broad-search alert.","Check for search.alert / timedout fields when results is absent.","Keep Count within limits (<= 20) so responses stay small and complete.","Verify the instance's Sourcegraph version matches the API shape the query assumes."],"tags":["graphql","schema","validation","sourcegraph"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}