{"record":{"id":"cd336f15c27c3e8f","repo":"JuliusBrussee/caveman","slug":"caveman-agent-standard-schema-cannot-emit-draft-0","errorCode":null,"errorMessage":"caveman agent: Standard Schema cannot emit draft-07 input JSON Schema","messagePattern":"caveman agent: Standard Schema cannot emit draft-07 input JSON Schema","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/primitives.ts","lineNumber":156,"sourceCode":"    throw new Error(`caveman agent: unknown tool result policy ${JSON.stringify(result)}`);\n  }\n  const timeoutMs = options.timeoutMs ?? 30_000;\n  if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {\n    throw new Error(\"caveman agent: tool timeoutMs must be a positive integer\");\n  }\n  const standard = standardToolSchema(options.input);\n  let input: TSchema;\n  if (standard === undefined) {\n    input = options.input as TSchema;\n  } else {\n    let converted = \"inputJSONSchema\" in options\n      ? options.inputJSONSchema\n      : undefined;\n    if (converted === undefined && standard.jsonSchema !== undefined) {\n      try {\n        converted = standard.jsonSchema.input({ target: \"draft-07\" });\n      } catch (error) {\n        throw new Error(\"caveman agent: Standard Schema cannot emit draft-07 input JSON Schema\", {\n          cause: error,\n        });\n      }\n    }\n    if (converted === undefined) {\n      throw new Error(\n        \"caveman agent: Standard Schema needs inputJSONSchema or Standard JSON Schema conversion\",\n      );\n    }\n    if (!isRecord(converted)) {\n      throw new Error(\"caveman agent: Standard Schema emitted invalid input JSON Schema\");\n    }\n    input = converted as TSchema;\n  }\n  const definition = {\n    kind: \"tool\",\n    name: options.name,\n    description: options.description,","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/primitives.ts#L138-L174","documentation":"When a tool's input is a Standard Schema (the vendor-neutral interface exposing a '~standard' property), tool() tries to obtain a draft-07 JSON Schema by calling standard.jsonSchema.input({ target: \"draft-07\" }) — the wire format models require. If the schema library's converter throws during that conversion, the error is wrapped as 'Standard Schema cannot emit draft-07 input JSON Schema' with the original error attached as cause.","triggerScenarios":"Using a Standard Schema validator whose jsonSchema converter cannot serialize some construct to draft-07 (e.g. draft-2020-only keywords, exotic formats, or symbols in the schema). The underlying converter error is in error.cause.","commonSituations":"Newer schema libraries defaulting to draft 2020-12, schemas using keywords with no draft-07 equivalent (e.g. prefixItems, some unevaluated* forms), or version drift between the schema library and this package's expectations.","solutions":["Inspect error.cause to see which schema construct failed to convert","Remove or replace draft-07-incompatible keywords from the input schema","Supply the JSON Schema directly via options.inputJSONSchema, bypassing conversion","Downgrade/switch the schema library to a version whose converter targets draft-07"],"exampleFix":"// before\nconst t = tool({\n  name: \"search\",\n  effect: \"read\",\n  input: mySchema, // mySchema uses prefixItems (draft 2020-12 only)\n  execute: ...,\n});\n\n// after\nconst t = tool({\n  name: \"search\",\n  effect: \"read\",\n  input: mySchema,\n  inputJSONSchema: {\n    type: \"object\",\n    properties: { query: { type: \"string\" } },\n    required: [\"query\"],\n  },\n  execute: ...,\n});","handlingStrategy":"try-catch","validationCode":"let draft07: unknown;\ntry {\n  draft07 = schema[\"~standard\"].jsonSchema?.input({ target: \"draft-07\" });\n} catch {\n  draft07 = undefined;\n}\nif (draft07 === undefined) {\n  // supply inputJSONSchema explicitly instead of letting tool() convert\n}","typeGuard":null,"tryCatchPattern":"try {\n  tool({ name, effect: \"read\", input: schema, execute });\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"draft-07\")) {\n    // inspect e.cause for the failing keyword; strip it or pass inputJSONSchema\n  }\n  throw e;\n}","preventionTips":["Avoid draft-2020-only keywords (prefixItems, unevaluated*) in tool input schemas","Pin schema library versions and test tool construction for every schema you ship","Prefer letting the factory derive JSON Schema from the validator over hand-writing both"],"tags":["json-schema","standard-schema","schema-conversion","compatibility"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}