{"record":{"id":"ba1f89f357fc6404","repo":"Budibase/budibase","slug":"could-not-parse-ai-response-as-valid-json","errorCode":null,"errorMessage":"Could not parse AI response as valid JSON.","messagePattern":"Could not parse AI response as valid JSON\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/automations/steps/ai/extract.ts","lineNumber":282,"sourceCode":"      typeof file !== \"string\"\n    ) {\n      extractInput = await processAttachmentFile(file, llm)\n    } else {\n      throw new Error(\"Invalid file input – source and file type do not match\")\n    }\n\n    const output = getOutputFromSchema(inputs.schema)\n    const modelMessages = buildExtractModelMessages(extractInput)\n    const providerOptions = llm.providerOptions?.(false)\n    const response = await generateText({\n      model: llm.chat,\n      messages: modelMessages,\n      providerOptions,\n      output,\n      experimental_download: downloadAssetsForExtract,\n    })\n    if (!response.output || response.output.data == null) {\n      throw new Error(\"Could not parse AI response as valid JSON.\")\n    }\n    const data = response.output.data\n\n    if (!data.length) {\n      throw new Error(\"Could not extract the requested data.\")\n    }\n\n    return {\n      data,\n      success: true,\n    }\n  } catch (err: any) {\n    console.error(\"Document extraction error:\", err)\n    return {\n      success: false,\n      data: {},\n      response: automationUtils.getError(err),\n    }","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/automations/steps/ai/extract.ts#L264-L300","documentation":"After generateText runs with a JSON output schema, run() expects response.output.data to exist. If the model produced no usable structured output (null/undefined output or data), the step cannot return extracted data and throws this parse error.","triggerScenarios":"generateText returns response with output == null or output.data == null — typically the model returned prose instead of schema-conformant JSON, or output parsing failed for the chosen model/provider.","commonSituations":"Model too weak to follow the JSON schema; temperature/prompting yielding non-JSON; provider quirks where experimental_output parsing fails; empty or non-document input confusing the model; unsupported model chosen for structured output.","solutions":["Switch to a stronger model that reliably supports structured/JSON output","Simplify or clarify the extraction schema and prompt instructions","Verify the input document actually contains the content to extract","Retry — transient model truncation can yield unparsable output","Check that the selected provider/model combination supports AI SDK JSON output mode"],"exampleFix":"// before\nmodel: weakModel, schema: veryDeepNestedSchema // prose output\n// after\nmodel: strongModel, schema: flatSchema, prompt with explicit \"respond only with JSON\"","handlingStrategy":"retry","validationCode":"// pre-flight: confirm the model supports structured output\nif (!modelSupportsJsonOutput(llm.model)) {\n  throw new Error(\"Selected model does not support structured output\")\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = await extractStep.run(inputs, ctx)\n} catch (err) {\n  if (err.message.includes(\"Could not parse AI response as valid JSON\")) {\n    // retry once with a stronger model or simplified schema\n  }\n  throw err\n}","preventionTips":["Use models known to support structured/JSON output","Keep extraction schemas simple and flat","Write explicit prompt instructions to output only schema-conformant JSON","Test the step with representative documents before production"],"tags":["ai","json","llm","parse"],"backgroundTag":"llm-invalid-json-output","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}