{"record":{"id":"68fe9a66c87057c9","repo":"continuedev/continue","slug":"failed-to-parse-greptile-response-rawtext","errorCode":null,"errorMessage":"Failed to parse Greptile response:\n${rawText}","messagePattern":"Failed to parse Greptile response:\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/context/providers/GreptileContextProvider.ts","lineNumber":97,"sourceCode":"      );\n      const rawText = await response.text();\n\n      // Check for HTTP errors\n      if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`);\n      }\n\n      // Parse the response as JSON\n      try {\n        const json = JSON.parse(rawText);\n        return json.sources.map((source: any) => ({\n          description: source.filepath,\n          content: `File: ${source.filepath}\\nLines: ${source.linestart}-${source.lineend}\\n\\n${source.summary}`,\n          name:\n            (source.filepath.split(\"/\").pop() ?? \"\").split(\"\\\\\").pop() ?? \"\",\n        }));\n      } catch (jsonError) {\n        throw new Error(`Failed to parse Greptile response:\\n${rawText}`);\n      }\n    } catch (error) {\n      console.error(\"Error getting context items from Greptile:\", error);\n      throw new Error(\"Error getting context items from Greptile\");\n    }\n  }\n\n  private getGreptileToken(): string | undefined {\n    return this.options.GreptileToken || process.env.GREPTILE_AUTH_TOKEN;\n  }\n\n  private getGithubToken(): string | undefined {\n    return this.options.GithubToken || process.env.GITHUB_TOKEN;\n  }\n\n  private async getWorkspaceDir(\n    extras: ContextProviderExtras,\n  ): Promise<string | null> {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/continuedev/continue/blob/5522c6f44ca0ac3528b37244818fbfa39b5af470/core/context/providers/GreptileContextProvider.ts#L79-L115","documentation":"JSON.parse of the Greptile response body failed, so the expected { sources: [...] } shape couldn't be extracted. rawText is embedded in the message. Note the outer catch (error 28) replaces this with a generic message before it reaches callers, so inspect console.error output to see this one.","triggerScenarios":"Greptile returns 200 with a non-JSON body (HTML error page, empty string, truncated stream) or a JSON shape where the sources mapping throws (e.g. sources undefined, source.filepath missing).","commonSituations":"Proxy or gateway intercepting the response; Greptile API contract change renaming fields; the .map callback throwing on unexpected data also lands here.","solutions":["Look at the console.error('Error getting context items from Greptile:') output for the raw text","Verify the Greptile API version/response shape with curl using the same payload","Guard source fields before mapping and return [] on unexpected shapes"],"exampleFix":"// before\n} catch (jsonError) {\n  throw new Error(`Failed to parse Greptile response:\\n${rawText}`);\n}\n// after\n} catch (jsonError) {\n  console.error('Greptile non-JSON response:', rawText?.slice(0, 300));\n  return [];\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isGreptileResponse(v: unknown): v is { sources: { filepath: string; linestart: number; lineend: number; summary: string }[] } {\n  return !!v && Array.isArray((v as any).sources);\n}","tryCatchPattern":"try { const json = JSON.parse(rawText); if (!isGreptileResponse(json)) return []; } catch { return []; }","preventionTips":["Validate external API shapes with type guards before mapping","Log raw response prefixes for shape-mismatch debugging"],"tags":["greptile","json","parse"],"backgroundTag":"invalid-json-response","analyzedSha":"5522c6f44ca0ac3528b37244818fbfa39b5af470","analyzedAt":"2026-08-27T11:28:54.683Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}