{"record":{"id":"44da9e8e5f37f5f8","repo":"coollabsio/coolify","slug":"this-source-is-being-used-by-an-application-pleas","errorCode":null,"errorMessage":"This source is being used by an application. Please delete all applications first.","messagePattern":"This source is being used by an application\\. Please delete all applications first\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"app/Models/GitlabApp.php","lineNumber":101,"sourceCode":"    }\n\n    public static function findByWebhookToken(string $token): ?self\n    {\n        if ($token === '') {\n            return null;\n        }\n\n        // Encrypted values cannot be matched with a SQL equality; sources are few per instance.\n        return static::query()->get()->first(\n            fn (self $app): bool => filled($app->webhook_token) && hash_equals((string) $app->webhook_token, $token)\n        );\n    }\n\n    protected static function booted(): void\n    {\n        static::deleting(function (GitlabApp $gitlabApp) {\n            if ($gitlabApp->applications()->count() > 0) {\n                throw new \\RuntimeException('This source is being used by an application. Please delete all applications first.');\n            }\n        });\n    }\n\n    public static function ownedByCurrentTeam()\n    {\n        return GitlabApp::where(function ($query) {\n            $query->where('team_id', currentTeam()->id)\n                ->orWhere('is_system_wide', true);\n        });\n    }\n\n    public static function public()\n    {\n        return GitlabApp::where(function ($query) {\n            $query->where('team_id', currentTeam()->id)->orWhere('is_system_wide', true);\n        })->where('is_public', true);\n    }","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Models/GitlabApp.php#L83-L119","documentation":"Thrown from a deleting hook in GitlabApp::booted() (app/Models/GitlabApp.php:101). Coolify blocks deletion of a GitLab source while the morph-count of applications attached via $gitlabApp->applications() is greater than zero, preventing orphaned applications whose deployments depend on that GitLab connection. It is the GitLab equivalent of the GitHub App delete guard, raised as a RuntimeException instead of \\Exception.","triggerScenarios":"Calling $gitlabApp->delete() (UI 'Delete' on a GitLab source) while at least one Application is related through the applications() relation. Bulk-deleting sources in a script without first detaching or removing dependent applications.","commonSituations":"Rotating GitLab instances (self-hosted → gitlab.com) and deleting the old source while projects still reference it; cleaning up 'unused' sources after a team audit without checking cross-project apps; scripts that wipe all GitlabApp rows for a team.","solutions":["List the dependents first: $gitlabApp->applications()->pluck('name') — delete those applications or re-point them to another GitLab source.","Retry the source deletion after the applications() count reaches zero.","For scripts, wrap deletion and skip sources that report dependents instead of failing the whole run."],"exampleFix":"// before\n$gitlabApp->delete(); // RuntimeException while apps remain\n\n// after\nif ($gitlabApp->applications()->exists()) {\n    // migrate or delete dependent apps first\n    return 'Source in use by: '.$gitlabApp->applications()->pluck('name')->implode(', ');\n}\n$gitlabApp->delete();","handlingStrategy":"validation","validationCode":"// Before deleting a GitLab source, check its applications\nif ($gitlabApp->applications()->exists()) {\n    // handle each application (delete or change source), then retry\n}","typeGuard":null,"tryCatchPattern":"try {\n    $gitlabApp->delete();\n} catch (\\RuntimeException $e) {\n    if (str_contains($e->getMessage(), 'being used by an application')) {\n        return 'Delete the applications attached to this GitLab source first.';\n    }\n    throw $e;\n}","preventionTips":["Audit applications()->count() before source deletion in scripts and skip in-use sources instead of aborting.","During GitLab migrations, keep the old source until every application has been re-pointed."],"tags":["coolify","gitlab","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"}