pocketbase/pocketbase · error
reached the max recursion level of view collection file fiel
Error message
reached the max recursion level of view collection file field queries
What it means
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.
Source
Thrown at core/view.go:218
}
// FindRecordByViewFile returns the original Record of the provided view collection file.
func (app *BaseApp) FindRecordByViewFile(viewCollectionModelOrIdentifier any, fileFieldName string, filename string) (*Record, error) {
view, err := getCollectionByModelOrIdentifier(app, viewCollectionModelOrIdentifier)
if err != nil {
return nil, err
}
if !view.IsView() {
return nil, errors.New("not a view collection")
}
var findFirstNonViewQueryFileField func(int) (*queryField, error)
findFirstNonViewQueryFileField = func(level int) (*queryField, error) {
// check the level depth to prevent infinite circular recursion
// (the limit is arbitrary and may change in the future)
if level > 5 {
return nil, errors.New("reached the max recursion level of view collection file field queries")
}
queryFields, err := parseQueryToFields(app, view.ViewQuery)
if err != nil {
return nil, err
}
for _, item := range queryFields {
if item.collection == nil ||
item.original == nil ||
item.field.GetName() != fileFieldName {
continue
}
if item.collection.IsView() {
view = item.collection
fileFieldName = item.original.GetName()
return findFirstNonViewQueryFileField(level + 1)View on GitHub (pinned to 5d217ddb50)
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.
Example fix
-- before: view_on_view_on_view ... >5 levels deep CREATE VIEW `deepView` AS SELECT file FROM `view5`; -- after: select from the base collection directly CREATE VIEW `deepView` AS SELECT file FROM `baseCollection`;
Defensive patterns
Strategy: validation
Try / catch
if _, err := app.FindRecordByViewFile(v, f, fn); err != nil {
if strings.Contains(err.Error(), "max recursion level") {
// notify: view nesting too deep or circular; flatten hierarchy
}
} Prevention
- 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).
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- no query file field found
- multiple statements are not supported
- wildcard columns (*) are not supported - manually type the c
- empty query
- validation_invalid_view_query
AI-assisted analysis of pocketbase/pocketbase@5d217ddb50 (2026-08-15).
Data as JSON: /api/errors/6834159207d7ad8d.
Report an issue: GitHub.