{"record":{"id":"6834159207d7ad8d","repo":"pocketbase/pocketbase","slug":"reached-the-max-recursion-level-of-view-collection","errorCode":null,"errorMessage":"reached the max recursion level of view collection file field queries","messagePattern":"reached the max recursion level of view collection file field queries","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/view.go","lineNumber":218,"sourceCode":"}\n\n// FindRecordByViewFile returns the original Record of the provided view collection file.\nfunc (app *BaseApp) FindRecordByViewFile(viewCollectionModelOrIdentifier any, fileFieldName string, filename string) (*Record, error) {\n\tview, err := getCollectionByModelOrIdentifier(app, viewCollectionModelOrIdentifier)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !view.IsView() {\n\t\treturn nil, errors.New(\"not a view collection\")\n\t}\n\n\tvar findFirstNonViewQueryFileField func(int) (*queryField, error)\n\tfindFirstNonViewQueryFileField = func(level int) (*queryField, error) {\n\t\t// check the level depth to prevent infinite circular recursion\n\t\t// (the limit is arbitrary and may change in the future)\n\t\tif level > 5 {\n\t\t\treturn nil, errors.New(\"reached the max recursion level of view collection file field queries\")\n\t\t}\n\n\t\tqueryFields, err := parseQueryToFields(app, view.ViewQuery)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tfor _, item := range queryFields {\n\t\t\tif item.collection == nil ||\n\t\t\t\titem.original == nil ||\n\t\t\t\titem.field.GetName() != fileFieldName {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif item.collection.IsView() {\n\t\t\t\tview = item.collection\n\t\t\t\tfileFieldName = item.original.GetName()\n\t\t\t\treturn findFirstNonViewQueryFileField(level + 1)","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/pocketbase/pocketbase/blob/5d217ddb50cb144d80a5d0b0bdf11b52b2c3e457/core/view.go#L200-L236","documentation":"FindRecordByViewFile walks a chain of nested view collections (a view whose query selects a file field of another view, and so on) to find the real backing collection. A guard limits this walk to 5 levels to prevent infinite recursion when views reference each other circularly. This error means the chain exceeded 5 nested view hops before reaching a non-view file field.","triggerScenarios":"A view A selecting a file field from view B, which selects from view C, etc. more than 5 levels deep; or two views that (directly or transitively) select from each other, creating a cycle, so the resolver can never reach a base collection.","commonSituations":"Incrementally stacking views on top of views during reporting/refactoring until the depth limit is crossed; circular view definitions introduced by editing a view query in the admin UI to reference another view that already references the first.","solutions":["Flatten the view hierarchy: make the top view query select the file field directly from a base (non-view) collection instead of through intermediate views.","Break any cycle: ensure no view's query, transitively, references itself.","If you genuinely need more depth, reduce nesting by consolidating the intermediate views' filters/joins into one query."],"exampleFix":"-- before: view_on_view_on_view ... >5 levels deep\nCREATE VIEW `deepView` AS SELECT file FROM `view5`;\n\n-- after: select from the base collection directly\nCREATE VIEW `deepView` AS SELECT file FROM `baseCollection`;","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := app.FindRecordByViewFile(v, f, fn); err != nil {\n    if strings.Contains(err.Error(), \"max recursion level\") {\n        // notify: view nesting too deep or circular; flatten hierarchy\n    }\n}","preventionTips":["Keep view hierarchies shallow (1-2 levels) by querying base collections directly.","When editing view SQL, check the referenced collections are not views that reference this one (avoid cycles)."],"tags":["pocketbase","view-collection","recursion","sql"],"backgroundTag":null,"analyzedSha":"5d217ddb50cb144d80a5d0b0bdf11b52b2c3e457","analyzedAt":"2026-08-15T10:06:33.165Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}