{"record":{"id":"35eacfbc71cd1040","repo":"vercel/ai","slug":"harness-cline-requires-a-json-schema-for-structu","errorCode":null,"errorMessage":"Harness 'cline' requires a JSON schema for structured output.","messagePattern":"Harness 'cline' requires a JSON schema for structured output\\.","errorType":"exception","errorClass":"HarnessCapabilityUnsupportedError","httpStatus":null,"severity":"error","filePath":"packages/harness-cline/src/cline-session.ts","lineNumber":586,"sourceCode":"    tools: ReadonlyArray<HarnessV1ToolSpec>;\n    instructions?: string;\n    emit: (part: HarnessV1StreamPart) => void;\n    abortSignal?: AbortSignal;\n    responseFormat?: HarnessV1PromptTurnOptions['responseFormat'];\n  }): Promise<HarnessV1PromptControl> {\n    if (stopped) {\n      throw new Error('Cline session has been stopped.');\n    }\n\n    const userTools = turnOpts.tools;\n    const skillsRuntime = createClineSkillsRuntime({\n      skills: turnOpts.skills,\n    });\n    if (\n      turnOpts.responseFormat?.type === 'json' &&\n      turnOpts.responseFormat.schema == null\n    ) {\n      throw new HarnessCapabilityUnsupportedError({\n        message:\n          \"Harness 'cline' requires a JSON schema for structured output.\",\n        harnessId: HARNESS_ID,\n      });\n    }\n    if (\n      turnOpts.responseFormat?.type === 'json' &&\n      agentModel.providerId === 'openai-codex-cli'\n    ) {\n      throw new HarnessCapabilityUnsupportedError({\n        message:\n          \"Harness 'cline' cannot require structured output with the openai-codex-cli provider because that provider does not expose external tools.\",\n        harnessId: HARNESS_ID,\n      });\n    }\n\n    if (turnOpts.model != null && turnOpts.model !== activeModelId) {\n      activeModelId = turnOpts.model;","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-cline/src/cline-session.ts#L568-L604","documentation":"When responseFormat.type is 'json', the Cline harness requires an explicit JSON schema because structured output is implemented through tools, which need a schema to shape the tool input. If schema is null/undefined, a HarnessCapabilityUnsupportedError is thrown naming the 'cline' harness. This is a capability check, not a data validation failure.","triggerScenarios":"Calling prompt/continueTurn with responseFormat: { type: 'json' } but omitting responseFormat.schema, e.g. responseFormat: { type: 'json', schema: undefined }.","commonSituations":"Assuming the harness can infer a schema; porting code from another harness/provider that accepts schemaless JSON mode; building responseFormat dynamically and the schema variable being undefined due to a failed zod-to-schema conversion.","solutions":["Provide a JSON schema: responseFormat: { type: 'json', schema: zodSchema(responseFormatSchema) } or an equivalent JSON Schema object.","If no schema exists, drop responseFormat entirely and parse/validate the model's text output yourself.","Check the resolved object at runtime (schema != null) before passing responseFormat to the session."],"exampleFix":"// before\nawait session.prompt({ text: 'Return JSON', responseFormat: { type: 'json' } });\n// after\nawait session.prompt({ text: 'Return JSON', responseFormat: { type: 'json', schema: z.object({ answer: z.string() }) } });","handlingStrategy":"validation","validationCode":"function assertValidJsonResponseFormat(rf?: { type?: string; schema?: unknown }) {\n  if (rf?.type === 'json' && rf.schema == null) {\n    throw new Error('responseFormat.type=json requires responseFormat.schema');\n  }\n}\nassertValidJsonResponseFormat(turnOpts.responseFormat);","typeGuard":null,"tryCatchPattern":"try {\n  await session.prompt(turnOpts);\n} catch (e) {\n  if (HarnessCapabilityUnsupportedError.isInstance(e) && e.message.includes('requires a JSON schema')) {\n    turnOpts = { ...turnOpts, responseFormat: { ...turnOpts.responseFormat!, schema: zodSchema(DefaultSchema) } };\n    await session.prompt(turnOpts);\n  } else throw e;\n}","preventionTips":["Build responseFormat objects through a helper that always pairs type:'json' with a schema.","Convert zod schemas via zodSchema() once and assert the result is non-null before passing.","Add a type-level requirement: define your responseFormat type so schema is required when type is 'json' (discriminated union)."],"tags":["structured-output","schema","capability","cline"],"backgroundTag":"missing-json-schema","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}