{"record":{"id":"7e5eebc4a3a9f2a2","repo":"pocketbase/pocketbase","slug":"s-failed-to-check-collection-references-w","errorCode":null,"errorMessage":"[%s] failed to check collection references: %w","messagePattern":"\\[(.+?)\\] failed to check collection references: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/collection_model.go","lineNumber":702,"sourceCode":"// -------------------------------------------------------------------\n\nfunc onCollectionDeleteExecute(e *CollectionEvent) error {\n\tif e.Collection.System {\n\t\treturn fmt.Errorf(\"[%s] system collections cannot be deleted\", e.Collection.Name)\n\t}\n\n\tdefer func() {\n\t\tif err := e.App.ReloadCachedCollections(); err != nil {\n\t\t\te.App.Logger().Warn(\"Failed to reload collections cache\", \"error\", err)\n\t\t}\n\t}()\n\n\tif !e.Collection.disableIntegrityChecks {\n\t\t// ensure that there aren't any existing references.\n\t\t// note: the select is outside of the transaction to prevent SQLITE_LOCKED error when mixing read&write in a single transaction\n\t\treferences, err := e.App.FindCollectionReferences(e.Collection, e.Collection.Id)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"[%s] failed to check collection references: %w\", e.Collection.Name, err)\n\t\t}\n\t\tif total := len(references); total > 0 {\n\t\t\tnames := make([]string, 0, len(references))\n\t\t\tfor ref := range references {\n\t\t\t\tnames = append(names, ref.Name)\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"[%s] failed to delete due to existing relation references: %s\", e.Collection.Name, strings.Join(names, \", \"))\n\t\t}\n\t}\n\n\toriginalApp := e.App\n\n\ttxErr := e.App.RunInTransaction(func(txApp App) error {\n\t\te.App = txApp\n\n\t\t// delete the related view or records table\n\t\tif e.Collection.IsView() {\n\t\t\tif err := txApp.DeleteView(e.Collection.Name); err != nil {","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/pocketbase/pocketbase/blob/5d217ddb50cb144d80a5d0b0bdf11b52b2c3e457/core/collection_model.go#L684-L720","documentation":"Before deleting a collection (with integrity checks on), PocketBase scans all other collections for relation fields pointing at the deleted one. This error wraps a failure of that lookup itself — a DB read error, not the presence of references.","triggerScenarios":"app.Delete(collection) when FindCollectionReferences fails: database is locked by a concurrent writer, the DB connection is broken, or another collection's stored field JSON is malformed so parsing references errors out.","commonSituations":"Deleting collections while heavy concurrent writes hold the DB; a corrupted _collections row with invalid fields JSON (often from hand edits or a failed import); running against a data.db that was replaced underneath a live process.","solutions":["Check the wrapped error — 'database is locked' means contention, a decode error names the bad collection","Retry the delete when the DB is quiet (no concurrent batch writes/jobs)","Repair or re-save the collection whose fields JSON fails to parse (Admin UI > edit > save regenerates it)","Ensure only one process has pb_data open (no stale server + CLI combo)"],"exampleFix":"// before: deleting during a bulk import\n// after: quiesce, then delete with a small guard\nif !c.System {\n    if err := app.Delete(c); err != nil {\n        log.Printf(\"delete %s failed: %v\", c.Name, err) // retry later\n    }\n}","handlingStrategy":"retry","validationCode":"// run during a quiet window\nif n, _ := app.DB().NewQuery(\"SELECT count(*) FROM pragma_lock_status\").Row(); /* contention check */ false {\n}","typeGuard":null,"tryCatchPattern":"var lastErr error\nfor attempt := 0; attempt < 3; attempt++ {\n    if err := app.Delete(c); err == nil { break } else {\n        if !strings.Contains(err.Error(), \"failed to check collection references\") { return err }\n        lastErr = err; time.Sleep(time.Duration(attempt+1) * 500 * time.Millisecond)\n    }\n}","preventionTips":["Schedule schema changes outside bulk-write windows","Keep one writer process per pb_data","Re-save suspicious collections to regenerate clean fields JSON"],"tags":["collections","delete","database","concurrency"],"backgroundTag":null,"analyzedSha":"5d217ddb50cb144d80a5d0b0bdf11b52b2c3e457","analyzedAt":"2026-08-15T10:06:33.165Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}