{"record":{"id":"7eb0594699b4dd54","repo":"makeplane/plane","slug":"slug-is-not-valid","errorCode":null,"errorMessage":"Slug is not valid","messagePattern":"Slug is not valid","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"apps/api/plane/db/models/workspace.py","lineNumber":116,"sourceCode":"            \"key\": True,\n            \"labels\": True,\n            \"link\": True,\n            \"priority\": True,\n            \"start_date\": True,\n            \"state\": True,\n            \"sub_issue_count\": True,\n            \"updated_on\": True,\n        }\n    }\n\n\ndef get_issue_props():\n    return {\"subscribed\": True, \"assigned\": True, \"created\": True, \"all_issues\": True}\n\n\ndef slug_validator(value):\n    if value in RESTRICTED_WORKSPACE_SLUGS:\n        raise ValidationError(\"Slug is not valid\")\n\n\nclass Workspace(BaseModel):\n    TIMEZONE_CHOICES = tuple(zip(pytz.common_timezones, pytz.common_timezones))\n\n    name = models.CharField(max_length=80, verbose_name=\"Workspace Name\")\n    logo = models.TextField(verbose_name=\"Logo\", blank=True, null=True)\n    logo_asset = models.ForeignKey(\n        \"db.FileAsset\",\n        on_delete=models.SET_NULL,\n        related_name=\"workspace_logo\",\n        blank=True,\n        null=True,\n    )\n    owner = models.ForeignKey(\n        settings.AUTH_USER_MODEL,\n        on_delete=models.CASCADE,\n        related_name=\"owner_workspace\",","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/api/plane/db/models/workspace.py#L98-L134","documentation":"Django ValidationError raised by `slug_validator` (workspace.py:113) when the proposed workspace slug is in the `RESTRICTED_WORKSPACE_SLUGS` list. That list (constants.py) reserves route-collision names such as `404`, `accounts`, `api`, `admin`, `sign-in`, `settings`, `profile`, `pages`, `billing`, `instance`, and ~60 others. The comparison is case-sensitive exact match.","triggerScenarios":"Creating or renaming a Workspace whose slug exactly equals a reserved entry (e.g. `admin`, `api`, `settings`, `sign-in`, `pages`). Triggered through the workspace create/rename serializer and model validator.","commonSituations":"A company named 'Pages' or 'Admin' trying to use their natural slug; importing orgs whose names collide with reserved routes; users picking slugs like `billing` or `profile` that the frontend also uses.","solutions":["Pick a slug not present in RESTRICTED_WORKSPACE_SLUGS - suffix it (e.g. `pages-team`, `admin-org`).","Check the reserved list at plane/utils/constants.py before submitting a slug.","Note matching is exact and case-sensitive, so `Admin` would currently pass - but rely on a clearly distinct slug rather than the case difference.","If a reserved slug is genuinely required, edit RESTRICTED_WORKSPACE_SLUGS (but verify no frontend route collision first)."],"exampleFix":"// before\nslug = \"admin\"\n\n// after\nslug = \"admin-team\"","handlingStrategy":"validation","validationCode":"from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS\n\ndef is_reserved_slug(slug: str) -> bool:\n    # mirrors workspace.py:115 slug_validator (exact, case-sensitive)\n    return slug in RESTRICTED_WORKSPACE_SLUGS","typeGuard":null,"tryCatchPattern":"from django.core.exceptions import ValidationError\ntry:\n    workspace.full_clean()\nexcept ValidationError as e:\n    if 'Slug is not valid' in str(e):\n        suggest_alternative(slug)","preventionTips":["Check the slug against RESTRICTED_WORKSPACE_SLUGS before submitting.","Suffix reserved-collision slugs (e.g. 'admin-team').","Treat the list as exact-match; prefer clearly distinct slugs."],"tags":["workspace","validation","slug","routing"],"backgroundTag":null,"analyzedSha":"1c8a60f858d8472aa56e29994ec1c7926da2c6ce","analyzedAt":"2026-08-12T14:44:31.636Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}