{"record":{"id":"141362526f531c2e","repo":"coollabsio/coolify","slug":"you-cannot-delete-this-github-app-because-it-is-in","errorCode":null,"errorMessage":"You cannot delete this GitHub App because it is in use by {applications_count} application(s). Delete them first.","messagePattern":"You cannot delete this GitHub App because it is in use by (.+?) application\\(s\\)\\. Delete them first\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Models/GithubApp.php","lineNumber":49,"sourceCode":"    protected $appends = ['type'];\n\n    protected $casts = [\n        'is_public' => 'boolean',\n        'is_system_wide' => 'boolean',\n        'type' => 'string',\n    ];\n\n    protected $hidden = [\n        'client_secret',\n        'webhook_secret',\n    ];\n\n    protected static function booted(): void\n    {\n        static::deleting(function (GithubApp $github_app) {\n            $applications_count = Application::where('source_id', $github_app->id)->count();\n            if ($applications_count > 0) {\n                throw new \\Exception('You cannot delete this GitHub App because it is in use by '.$applications_count.' application(s). Delete them first.');\n            }\n\n            $privateKey = $github_app->privateKey;\n            if ($privateKey) {\n                // Check if key is used by anything EXCEPT this GitHub app\n                $isUsedElsewhere = $privateKey->servers()->exists()\n                    || $privateKey->applications()->exists()\n                    || $privateKey->githubApps()->where('id', '!=', $github_app->id)->exists()\n                    || $privateKey->gitlabApps()->exists();\n\n                if (! $isUsedElsewhere) {\n                    $privateKey->delete();\n                } else {\n                }\n            }\n        });\n    }\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Models/GithubApp.php#L31-L67","documentation":"Thrown from a model deleting hook registered in GithubApp::booted() (app/Models/GithubApp.php:49). Coolify refuses to delete a GitHub App source while any Application row still references it via source_id, because deleting it would orphan the apps' Git integration. The same hook also cascades deletion of the app's PrivateKey, but only when that key is not used by any server, other application, or other Git app — the guard runs before any of that happens.","triggerScenarios":"Calling $githubApp->delete() (the UI 'Delete' action on a GitHub source under Security → GitHub Apps) while Application::where('source_id', $github_app->id)->count() > 0. Any single application created from that GitHub App — including deleted-but-not-purged or preview-environment apps — triggers it.","commonSituations":"Cleaning up unused Git sources during an org restructure while apps still point at them; bulk scripts that delete sources before apps; forgetting that an old app in another project/environment still uses the source; teams migrated off a GitHub App to a different auth method without editing every app's source.","solutions":["Delete (or move to another source) every application that uses this GitHub App first: run Application::where('source_id', $githubApp->id)->get() and handle each one.","If apps must keep deploying, point them at a different/other source (update source_id) instead of deleting the app.","Retry $githubApp->delete() once the count is zero — the private-key cascade then runs automatically.","In shared instances, search all teams/projects for apps referencing the source, not just the project you are looking at."],"exampleFix":"// before\n$githubApp->delete(); // throws if any app still uses it\n\n// after — guard the delete with a precheck and clear dependents\n$inUse = Application::where('source_id', $githubApp->id)->pluck('name');\nif ($inUse->isNotEmpty()) {\n    throw new \\Exception('Cannot delete: still used by '.$inUse->implode(', '));\n}\n$githubApp->delete();","handlingStrategy":"validation","validationCode":"// Before deleting a GitHub App, check for dependents\n$inUse = Application::where('source_id', $githubApp->id)->exists();\nif ($inUse) {\n    // delete or re-point those applications first\n}","typeGuard":null,"tryCatchPattern":"try {\n    $githubApp->delete();\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'in use by')) {\n        $count = Application::where('source_id', $githubApp->id)->count();\n        return \"Delete blocked: {$count} application(s) still use this GitHub App.\";\n    }\n    throw $e;\n}","preventionTips":["Always resolve dependents before deleting Git sources; the count in the message tells you how many remain.","When migrating auth, re-point applications to the new source instead of deleting the old one first.","In cleanup scripts, delete applications before their sources, never the reverse order."],"tags":["coolify","github-app","git-source","delete-guard","eloquent-model-events"],"backgroundTag":"delete-blocked-by-references","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}