{"record":{"id":"6f3b0715d73be30c","repo":"HumanSignal/label-studio","slug":"can-t-find-organization-by-welcome-url-url","errorCode":null,"errorMessage":"Can't find Organization by welcome URL: {url}","messagePattern":"Can't find Organization by welcome URL: (.+?)","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"label_studio/organizations/models.py","lineNumber":143,"sourceCode":"\n    @classmethod\n    def find_by_user(cls, user, check_deleted=False):\n        memberships = OrganizationMember.objects.filter(user=user).prefetch_related('organization')\n        if not memberships.exists():\n            raise ValueError(f'No memberships found for user {user}')\n        membership = memberships.first()\n        if check_deleted:\n            return (membership.organization, True) if membership.deleted_at else (membership.organization, False)\n\n        return membership.organization\n\n    @classmethod\n    def find_by_invite_url(cls, url):\n        token = url.strip('/').split('/')[-1]\n        if len(token):\n            return Organization.objects.get(token=token)\n        else:\n            raise KeyError(f\"Can't find Organization by welcome URL: {url}\")\n\n    def has_user(self, user):\n        return self.users.filter(pk=user.pk).exists()\n\n    def has_deleted(self, user):\n        return OrganizationMember.objects.filter(user=user, organization=self, deleted_at__isnull=False).exists()\n\n    def has_project_member(self, user):\n        return self.projects.filter(members__user=user).exists()\n\n    def has_permission(self, user):\n        return OrganizationMember.objects.filter(user=user, organization=self, deleted_at__isnull=True).exists()\n\n    def add_user(self, user):\n        if _workforce_closure_blocked(user):\n            # A closed identity must never gain a NEW membership anywhere — this is the one\n            # chokepoint every membership creation goes through (invites, SCIM, SAML, LDAP, admin).\n            logger.warning(","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/organizations/models.py#L125-L161","documentation":"Organization.find_by_invite_url parses the last path segment of a welcome/invite URL as a token and raises KeyError when the token is empty. Note it does NOT catch DoesNotExist — an invalid non-empty token still raises Organization.DoesNotExist from .get(); this KeyError only fires for URLs whose stripped value has no trailing segment.","triggerScenarios":"Calling Organization.find_by_invite_url with an empty string, '', a URL like 'https://host/invite' with nothing after the last slash, or a URL that reduces to no token after strip('/').split('/').","commonSituations":"Misconfigured WELCOME_URL / invite link template missing the token; env var or org setting blank; copying the invite base URL without the token; trailing formatting stripping the token client-side.","solutions":["Inspect the URL — it must end with a non-empty token segment","Re-generate the invite link from the organization settings page","Check the org's token field is populated in the DB (Organization.token)","Verify the env/config that injects the token into the welcome URL"],"exampleFix":"// before\norg = Organization.find_by_invite_url(invite_url)  # invite_url may be ''\n// after\nif not invite_url or not invite_url.strip('/').split('/')[-1]:\n    raise ImproperlyConfigured('Invite URL missing token')\norg = Organization.find_by_invite_url(invite_url)","handlingStrategy":"validation","validationCode":"token = url.strip('/').split('/')[-1] if url else ''\nif not token:\n    raise ImproperlyConfigured('invite URL has no token segment')","typeGuard":null,"tryCatchPattern":"try:\n    org = Organization.find_by_invite_url(url)\nexcept KeyError:\n    ...  # empty token — fix URL config\nexcept Organization.DoesNotExist:\n    ...  # token not recognized — link expired/regenerated","preventionTips":["Validate invite URL templates in env settings at startup","Never trim trailing path segments from invite links","Ensure Organization.token is generated on org creation","Log full URL on failure to diagnose config issues"],"tags":["django","invite-link","url-parsing"],"backgroundTag":"invalid-invite-url","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}