{"record":{"id":"4d24fdfbfe373f73","repo":"JuliusBrussee/caveman","slug":"caveman-agent-tool-standard-json-schema-converter","errorCode":null,"errorMessage":"caveman agent: tool Standard JSON Schema converter is invalid","messagePattern":"caveman agent: tool Standard JSON Schema converter is invalid","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/primitives.ts","lineNumber":221,"sourceCode":"  return Object.freeze(definition);\n}\n\nfunction standardToolSchema(\n  value: unknown,\n): StandardSchemaV1.Props<unknown, unknown> & {\n  jsonSchema?: StandardJSONSchemaV1.Converter;\n} | undefined {\n  if (!isRecord(value) || !isRecord(value[\"~standard\"])) return undefined;\n  const standard = value[\"~standard\"];\n  if (standard.version !== 1 || typeof standard.vendor !== \"string\" ||\n      typeof standard.validate !== \"function\") {\n    throw new Error(\n      \"caveman agent: tool Standard Schema must implement version 1 validation\",\n    );\n  }\n  if (standard.jsonSchema !== undefined &&\n      (!isRecord(standard.jsonSchema) || typeof standard.jsonSchema.input !== \"function\")) {\n    throw new Error(\"caveman agent: tool Standard JSON Schema converter is invalid\");\n  }\n  return standard as unknown as StandardSchemaV1.Props<unknown, unknown> & {\n    jsonSchema?: StandardJSONSchemaV1.Converter;\n  };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction artifactResultPolicy(definition: ArtifactDefinition): ToolResultPolicy {\n  if (definition.strategy === \"verbatim\") {\n    return definition.recovery === \"exact_ccr\" ? \"exact_ccr\" : \"inline\";\n  }\n  if (definition.strategy === \"json-index\") return \"compress\";\n  return \"page\";\n}\n","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/primitives.ts#L203-L239","documentation":"Thrown by the tool() builder's standardToolSchema() probe when a tool schema advertises a Standard Schema '~standard' props object whose optional jsonSchema converter is malformed. The framework uses that converter (StandardJSONSchemaV1.Converter, which must expose an input() function) to lower the schema to JSON Schema for the provider; if jsonSchema exists but is not an object with a callable input property, the tool definition is rejected at construction time.","triggerScenarios":"Calling tool({...}) with a schema object that has a '~standard' props bag where standard.jsonSchema is set to a non-record (e.g. a string or array) or is a record whose input is not a function. Typically a hand-rolled Standard Schema implementation or a wrapper library that attaches a partial jsonSchema object.","commonSituations":"Writing a custom Standard Schema v1 wrapper for a tool and stubbing jsonSchema as a plain schema object instead of a converter; upgrading a schema library that changed the jsonSchema converter shape; copying the StandardSchemaV1.Props interface but forgetting the converter's method form.","solutions":["Make standard.jsonSchema an object with an input() function: { input: (schema) => jsonSchemaObject } — or omit jsonSchema entirely so the framework falls back to its own conversion","If using Zod/Valibot/ArkType/TypeBox through their official Standard Schema support, pass the library's own exported schema instead of a rewrapped props object","If you do not need the Standard Schema path, pass a TypeBox TSchema (the framework's native schema type) as the tool's input schema"],"exampleFix":"// before\nconst schema = {\n  '~standard': {\n    version: 1,\n    vendor: 'my-lib',\n    validate: (v) => ({ value: v }),\n    jsonSchema: { type: 'object' }, // wrong: plain schema, not a converter\n  },\n};\ntool({ name: 't', schema, execute: async () => {} });\n\n// after\nconst schema = {\n  '~standard': {\n    version: 1,\n    vendor: 'my-lib',\n    validate: (v) => ({ value: v }),\n    jsonSchema: { input: () => ({ type: 'object' }) }, // converter with input()\n  },\n};\ntool({ name: 't', schema, execute: async () => {} });","handlingStrategy":"type-guard","validationCode":"function hasValidStandardJsonSchema(schema: unknown): boolean {\n  const props = (schema as { '~standard'?: unknown })?.['~standard'];\n  if (props === null || typeof props !== 'object') return true; // no standard path, fine\n  const js = (props as { jsonSchema?: unknown }).jsonSchema;\n  if (js === undefined) return true;\n  return typeof js === 'object' && js !== null &&\n    typeof (js as { input?: unknown }).input === 'function';\n}","typeGuard":"function isValidStandardToolSchema(value: unknown): value is { '~standard': { version: 1; vendor: string; validate: () => unknown; jsonSchema?: { input: (s: unknown) => unknown } } } {\n  if (typeof value !== 'object' || value === null) return false;\n  const s = (value as Record<string, unknown>)['~standard'];\n  if (typeof s !== 'object' || s === null) return false;\n  const p = s as Record<string, unknown>;\n  if (p.version !== 1 || typeof p.vendor !== 'string' || typeof p.validate !== 'function') return false;\n  const js = p.jsonSchema;\n  if (js !== undefined && (typeof js !== 'object' || js === null || typeof (js as Record<string, unknown>).input !== 'function')) return false;\n  return true;\n}","tryCatchPattern":"try { tool({ name, schema, execute }); } catch (e) { if (e instanceof Error && e.message.includes('Standard JSON Schema converter')) throw new ConfigError(`tool ${name}: fix or drop schema['~standard'].jsonSchema`, { cause: e }); throw e; }","preventionTips":["Prefer library-native Standard Schema exports (Zod/Valibot/ArkType) over hand-rolled '~standard' objects","Treat jsonSchema as optional: omit it unless you specifically need custom JSON Schema lowering","Unit-test every custom schema wrapper against the tool() builder"],"tags":["validation","schema","tool-definition","standard-schema"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}