{"record":{"id":"8edaf7873d9bacd4","repo":"vercel/ai","slug":"recursive-reference-detected-at-refs-currentpath","errorCode":null,"errorMessage":"Recursive reference detected at ${refs.currentPath.join('/')}! Defaulting to any","messagePattern":"Recursive reference detected at (.+?)! Defaulting to any","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/provider-utils/src/to-json-schema/zod3-to-json-schema/parse-def.ts","lineNumber":86,"sourceCode":"  refs: Refs,\n):\n  | {\n      $ref: string;\n    }\n  | {}\n  | undefined => {\n  switch (refs.$refStrategy) {\n    case 'root':\n      return { $ref: item.path.join('/') };\n    case 'relative':\n      return { $ref: getRelativePath(refs.currentPath, item.path) };\n    case 'none':\n    case 'seen': {\n      if (\n        item.path.length < refs.currentPath.length &&\n        item.path.every((value, index) => refs.currentPath[index] === value)\n      ) {\n        console.warn(\n          `Recursive reference detected at ${refs.currentPath.join(\n            '/',\n          )}! Defaulting to any`,\n        );\n\n        return parseAnyDef();\n      }\n\n      return refs.$refStrategy === 'seen' ? parseAnyDef() : undefined;\n    }\n  }\n};\n\nconst addMeta = (\n  def: ZodTypeDef,\n  refs: Refs,\n  jsonSchema: JsonSchema7Type,\n): JsonSchema7Type => {","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/provider-utils/src/to-json-schema/zod3-to-json-schema/parse-def.ts#L68-L104","documentation":"During zod v3 schema-to-JSON-Schema conversion, a recursive ($ref) definition is encountered a second time while already being resolved, i.e. the cycle cannot be represented at the current path, so the converter emits this warning and substitutes an \"any\" JSON schema for that node. The resulting JSON Schema is therefore less precise than the zod schema.","triggerScenarios":"Calling zodToJsonSchema (zod3toJSONSchema) on a zod schema containing recursive references (e.g. a self-referencing object or lazy() type) whose cycle resolution mode cannot emit a $ref at that position (path/refs settings).","commonSituations":"Converting tree-like zod schemas (comments, categories, nested menus) for structured output with generateObject or provider tool schemas; passing a 'seen' cycle handling mode where $ref is unsupported.","solutions":["Use the cycle handling option that emits $refs (e.g. zodToJsonSchema(schema, { cycle: 'ref' })) instead of 'none'/'seen'.","Restructure the zod schema to break the recursion (depth cap, iterative shape) so conversion succeeds without cycles.","Manually define the recursive part of the JSON Schema and merge it with the converted output.","Treat the warning as acceptable if 'any' at that node is tolerable."],"exampleFix":"// before\nconst jsonSchema = zod3ToJSONSchema(recursiveSchema); // warns, any at cycle\n// after\nconst jsonSchema = zod3ToJSONSchema(recursiveSchema, { cycle: 'ref' });","handlingStrategy":"validation","validationCode":"// detect recursion before converting\nfunction isRecursive(zodSchema) { /* walk .def / .shape checking self references */ }\n// or: opt into $ref cycle handling up front\nzod3ToJSONSchema(schema, { cycle: 'ref' });","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer cycle: 'ref' when converting schemas that may be recursive","Spot-check generated JSON Schema for 'any' nodes in tests","Avoid lazy()/self-referencing zod types in schemas destined for strict JSON Schema consumers"],"tags":["json-schema","zod","recursion","schema-conversion"],"backgroundTag":"recursive-schema-conversion","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}