{"record":{"id":"7c517f3de04a5e8a","repo":"makeplane/plane","slug":"5112","errorCode":"5112","errorMessage":"GITEA_NOT_CONFIGURED","messagePattern":"GITEA_NOT_CONFIGURED","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"apps/api/plane/authentication/provider/oauth/gitea.py","lineNumber":43,"sourceCode":"        (GITEA_CLIENT_ID, GITEA_CLIENT_SECRET, GITEA_HOST) = get_configuration_value(\n            [\n                {\n                    \"key\": \"GITEA_CLIENT_ID\",\n                    \"default\": os.environ.get(\"GITEA_CLIENT_ID\"),\n                },\n                {\n                    \"key\": \"GITEA_CLIENT_SECRET\",\n                    \"default\": os.environ.get(\"GITEA_CLIENT_SECRET\"),\n                },\n                {\n                    \"key\": \"GITEA_HOST\",\n                    \"default\": os.environ.get(\"GITEA_HOST\"),\n                },\n            ]\n        )\n\n        if not (GITEA_CLIENT_ID and GITEA_CLIENT_SECRET and GITEA_HOST):\n            raise AuthenticationException(\n                error_code=AUTHENTICATION_ERROR_CODES[\"GITEA_NOT_CONFIGURED\"],\n                error_message=\"GITEA_NOT_CONFIGURED\",\n            )\n\n        # Enforce scheme and normalize trailing slash(es)\n        parsed = urlparse(GITEA_HOST)\n        if not parsed.scheme or parsed.scheme not in (\"https\", \"http\"):\n            raise AuthenticationException(\n                error_code=AUTHENTICATION_ERROR_CODES[\"GITEA_NOT_CONFIGURED\"],\n                error_message=\"GITEA_NOT_CONFIGURED\",  # avoid leaking details to query params\n            )\n        GITEA_HOST = GITEA_HOST.rstrip(\"/\")\n\n        # Set URLs based on the host\n        self.token_url = f\"{GITEA_HOST}/login/oauth/access_token\"\n        self.userinfo_url = f\"{GITEA_HOST}/api/v1/user\"\n\n        client_id = GITEA_CLIENT_ID","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/api/plane/authentication/provider/oauth/gitea.py#L25-L61","documentation":"Raised in the Gitea OAuth provider (gitea.py:43) when any of GITEA_CLIENT_ID, GITEA_CLIENT_SECRET, or GITEA_HOST is falsy, OR (second raise, same code) when GITEA_HOST has no scheme or a scheme other than http/https. Code 5112. The scheme check deliberately reuses GITEA_NOT_CONFIGURED to avoid leaking validation details into OAuth redirect query params.","triggerScenarios":"Constructing the Gitea OAuth provider reads the three GITEA_* values from instance config/env. If any is empty, AuthenticationException code 5112 is raised. Separately, urlparse(GITEA_HOST) must yield a scheme in (http, https) or the same error is raised. Hit by initiating or completing Gitea OAuth on a misconfigured instance.","commonSituations":"Gitea OAuth app not yet registered (missing client id/secret); GITEA_HOST entered as bare hostname without https:// (e.g. 'gitea.example.com' instead of 'https://gitea.example.com'); partial config after enabling Gitea integration.","solutions":["Set GITEA_CLIENT_ID, GITEA_CLIENT_SECRET, and GITEA_HOST (with scheme) in instance config/env.","Format GITEA_HOST as a full URL: 'https://gitea.example.com' (trailing slash is normalized away).","If Gitea is not intended, remove the Gitea OAuth entry from the UI/discovery so users cannot select it."],"exampleFix":"# before: GITEA_HOST=gitea.example.com  (no scheme) -> 5112\n# GITEA_HOST=https://gitea.example.com\n# GITEA_CLIENT_ID=<id>\n# GITEA_CLIENT_SECRET=<secret>\n# after: provider constructs and OAuth redirect proceeds","handlingStrategy":"validation","validationCode":"import os\nfrom urllib.parse import urlparse\nfrom plane.license.utils.instance_value import get_configuration_value\n\ndef gitea_configured() -> bool:\n    cid, secret, host = get_configuration_value([\n        {'key': 'GITEA_CLIENT_ID', 'default': os.environ.get('GITEA_CLIENT_ID')},\n        {'key': 'GITEA_CLIENT_SECRET', 'default': os.environ.get('GITEA_CLIENT_SECRET')},\n        {'key': 'GITEA_HOST', 'default': os.environ.get('GITEA_HOST')},\n    ])\n    if not (cid and secret and host):\n        return False\n    p = urlparse(host)\n    return p.scheme in ('http', 'https')","typeGuard":null,"tryCatchPattern":"try:\n    GiteaProvider(request, ...)\nexcept AuthenticationException as e:\n    if e.error_code == 5112:\n        hide_gitea_option_or_show_config_guide()\n    else:\n        raise","preventionTips":["Always include the scheme in GITEA_HOST (https://...).","Set all three GITEA_* values together; partial config triggers 5112.","Validate OAuth provider config at deploy time."],"tags":["authentication","oauth","gitea","configuration","env"],"backgroundTag":null,"analyzedSha":"1c8a60f858d8472aa56e29994ec1c7926da2c6ce","analyzedAt":"2026-08-12T14:44:31.636Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}