{"record":{"id":"c00820bac2be8b19","repo":"microsoft/playwright","slug":"failed-to-parse-response-text","errorCode":null,"errorMessage":"Failed to parse response: ${text}","messagePattern":"Failed to parse response: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/recorder/chat.ts","lineNumber":52,"sourceCode":"  }\n\n  clearHistory() {\n    this._history = [];\n  }\n\n  async post<T>(prompt: string): Promise<T | null> {\n    await this._append('user', prompt);\n    let text = await asString(await this._post());\n    if (text.startsWith('```json') && text.endsWith('```'))\n      text = text.substring('```json'.length, text.length - '```'.length);\n    for (let i = 0; i < 3; ++i) {\n      try {\n        return JSON.parse(text);\n      } catch (e) {\n        await this._append('user', String(e));\n      }\n    }\n    throw new Error('Failed to parse response: ' + text);\n  }\n\n  private async _append(user: ChatMessage['user'], content: string) {\n    this._history.push({ user, content });\n  }\n\n  private async _connection(): Promise<Connection> {\n    if (!this._connectionPromise) {\n      this._connectionPromise = WebSocketTransport.connect(undefined, this._wsEndpoint).then(transport => {\n        return new Connection(transport, (method, params) => this._dispatchEvent(method, params), () => {});\n      });\n    }\n    return this._connectionPromise;\n  }\n\n  private _dispatchEvent(method: string, params: any) {\n    if (method === 'chatChunk') {\n      const { chatId, chunk } = params;","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/recorder/chat.ts#L34-L70","documentation":"Thrown by the recorder Chat client (the AI assistant used by the test recorder) when the model's response cannot be JSON.parse'd after three retry attempts. Each failure appends the parse error back to the conversation to nudge the model, but if it still does not return valid JSON the client gives up.","triggerScenarios":"The chat/LLM endpoint returns malformed JSON, prose around JSON, code fences that are not stripped, or truncated output; the model ignores repeated 'return JSON' instructions; the WebSocket endpoint is misconfigured and returns unexpected content.","commonSituations":"Using the experimental AI recorder/chat with a flaky or non-conformant backend; model output exceeding token limits producing truncated JSON; network issues corrupting the streamed response.","solutions":["Retry the chat request (transient model non-compliance often succeeds on a new run).","Verify the configured chat WebSocket endpoint is correct and reachable.","Simplify the prompt so the model returns a shorter, well-formed JSON payload; if the issue persists, report it as a tooling bug since JSON conformance is the model's contract."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"let result = null;\nfor (let i = 0; i < 3 && !result; ++i) {\n  try {\n    result = await chat.post('...');\n  } catch (e) {\n    if (/Failed to parse response/.test(e.message) && i < 2) continue;\n    throw e;\n  }\n}","preventionTips":["Keep prompts concise so the model returns well-formed, non-truncated JSON.","Verify the configured chat WebSocket endpoint is reachable and correct.","Treat persistent parse failures as a tooling/backend bug and report them."],"tags":["recorder","chat","llm","json-parse","experimental"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}