{"record":{"id":"da81192d49538f09","repo":"coollabsio/coolify","slug":"unknown-notification-channel-channel","errorCode":null,"errorMessage":"Unknown notification channel [{$channel}].","messagePattern":"Unknown notification channel \\[(.+?)\\]\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"app/Http/Controllers/Api/NotificationsController.php","lineNumber":181,"sourceCode":"                    'webhook_enabled' => 'sometimes|boolean',\n                    'webhook_url' => ['sometimes', 'nullable', 'string', new SafeWebhookUrl],\n                    'deployment_success_webhook_notifications' => 'sometimes|boolean',\n                    'deployment_failure_webhook_notifications' => 'sometimes|boolean',\n                    'status_change_webhook_notifications' => 'sometimes|boolean',\n                    'backup_success_webhook_notifications' => 'sometimes|boolean',\n                    'backup_failure_webhook_notifications' => 'sometimes|boolean',\n                    'scheduled_task_success_webhook_notifications' => 'sometimes|boolean',\n                    'scheduled_task_failure_webhook_notifications' => 'sometimes|boolean',\n                    'docker_cleanup_success_webhook_notifications' => 'sometimes|boolean',\n                    'docker_cleanup_failure_webhook_notifications' => 'sometimes|boolean',\n                    'server_disk_usage_webhook_notifications' => 'sometimes|boolean',\n                    'server_reachable_webhook_notifications' => 'sometimes|boolean',\n                    'server_unreachable_webhook_notifications' => 'sometimes|boolean',\n                    'server_patch_webhook_notifications' => 'sometimes|boolean',\n                    'traefik_outdated_webhook_notifications' => 'sometimes|boolean',\n                ],\n            ],\n            default => throw new \\InvalidArgumentException(\"Unknown notification channel [{$channel}].\"),\n        };\n    }\n\n    /**\n     * @return list<string>\n     */\n    private function allowedFields(string $channel): array\n    {\n        $config = $this->channelConfig($channel);\n        /** @var Model $model */\n        $model = new $config['model'];\n\n        return array_values(array_filter(\n            $model->getFillable(),\n            fn (string $field): bool => $field !== 'team_id'\n        ));\n    }\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Http/Controllers/Api/NotificationsController.php#L163-L199","documentation":"NotificationsController::channelConfig() is a PHP match over the channel string with arms for 'email', 'discord', 'slack', 'telegram', and 'webhook'; any other value falls into default and throws InvalidArgumentException('Unknown notification channel [...]'). The channel string comes from the {channel} route segment of the notifications API endpoints.","triggerScenarios":"Calling /api/v1/notifications/{channel} or the update endpoint with a misspelled or unregistered channel (e.g. 'Email', 'teams', 'smtp', 'webhooks'); passing a channel that exists in the UI but was never added to this match statement.","commonSituations":"API consumers guessing endpoint names; case mismatches ('Slack' vs 'slack'); trailing whitespace or slashes in the URL segment; forks adding a new channel type in the frontend but not in channelConfig().","solutions":["Use one of the supported lowercase channel names exactly: email, discord, slack, telegram, webhook.","Check the route parameter for typos, capitalization, or trailing characters.","If you extended Coolify with a new channel, add a match arm in channelConfig() plus the corresponding show/update routes and allowed fields."],"exampleFix":"// before: unmatched channel falls through to the throw\n$channel = $request->route('channel'); // 'teams'\n$config = $this->channelConfig($channel);\n\n// after: validate against the supported set first\n$channel = strtolower(trim((string) $request->route('channel')));\nif (! in_array($channel, ['email', 'discord', 'slack', 'telegram', 'webhook'], true)) {\n    abort(404, \"Unsupported notification channel '{$channel}'. Supported: email, discord, slack, telegram, webhook.\");\n}\n$config = $this->channelConfig($channel);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"/** @param mixed $channel */\nfunction isValidNotificationChannel($channel): bool\n{\n    return is_string($channel)\n        && in_array(strtolower(trim($channel)), ['email', 'discord', 'slack', 'telegram', 'webhook'], true);\n}","tryCatchPattern":"try {\n    $config = $this->channelConfig($channel);\n} catch (\\InvalidArgumentException $e) {\n    if (str_starts_with($e->getMessage(), 'Unknown notification channel')) {\n        abort(404, 'Supported channels: email, discord, slack, telegram, webhook.');\n    }\n    throw $e;\n}","preventionTips":["Normalize the route segment (strtolower + trim) before dispatching to channelConfig().","Expose the supported channel list in API docs and derive route constraints from it (Route::pattern or whereIn('channel', ...)).","When adding a channel, update the match arms, allowedFields(), routes, and docs in one change."],"tags":["api","notifications","validation","channel","route-parameter"],"backgroundTag":"unsupported-channel","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}