{"record":{"id":"5fbc02e121ee068c","repo":"infiniflow/ragflow","slug":"the-calling-user-does-not-have-permission","errorCode":null,"errorMessage":"The calling user does not have permission","messagePattern":"The calling user does not have permission","errorType":"http","errorClass":"ApiPermissionError","httpStatus":403,"severity":"warning","filePath":"common/data_source/confluence_connector.py","lineNumber":790,"sourceCode":"        Implements a method that isn't in the third party client.\n\n        Get information about the current user\n        :param expand: OPTIONAL expand for get status of user.\n                Possible param is \"status\". Results are \"Active, Deactivated\"\n        :return: Returns the user details\n        \"\"\"\n\n        from atlassian.errors import ApiPermissionError  # type:ignore\n\n        url = \"rest/api/user/current\"\n        params = {}\n        if expand:\n            params[\"expand\"] = expand\n        try:\n            response = self.get(url, params=params)\n        except HTTPError as e:\n            if e.response.status_code == 403:\n                raise ApiPermissionError(\"The calling user does not have permission\", reason=e)\n            raise\n        return response\n\n\ndef get_user_email_from_username__server(confluence_client: OnyxConfluence, user_name: str) -> str | None:\n    global _USER_EMAIL_CACHE\n    if _USER_EMAIL_CACHE.get(user_name) is None:\n        try:\n            response = confluence_client.get_mobile_parameters(user_name)\n            email = response.get(\"email\")\n        except Exception:\n            logging.warning(f\"failed to get confluence email for {user_name}\")\n            # For now, we'll just return None and log a warning. This means\n            # we will keep retrying to get the email every group sync.\n            email = None\n            # We may want to just return a string that indicates failure so we don't\n            # keep retrying\n            # email = f\"FAILED TO GET CONFLUENCE EMAIL FOR {user_name}\"","sourceCodeStart":772,"sourceCodeEnd":808,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/confluence_connector.py#L772-L808","documentation":"An atlassian ApiPermissionError raised by OnyxConfluence.get_mobile_parameters (a monkey-patched Confluence client method) when GET rest/api/user/current returns HTTP 403. The patch maps 403 to a permission error with this message, preserving the original HTTPError as reason. It surfaces during user-lookup helpers (e.g. get_user_email_from_username__server) that resolve usernames to emails on Confluence Server.","triggerScenarios":"Calling get_user_current/get_mobile_parameters with credentials whose user lacks permission to view the current-user or target-user profile: a read-only service account, a user restricted by space-level permissions, or Confluence Server global permissions denying profile viewing. Also 403 from a reverse proxy/WAF in front of Confluence, and SSO-only instances rejecting PAT/basic auth.","commonSituations":"Personal Access Token created by a low-privilege Server user used for document ingestion (fetching document metadata triggers user lookups); SSO/SAML enforcement making basic auth return 403 on user endpoints; reverse-proxy IP allowlists blocking the indexing host.","solutions":["Use credentials of a user with permission to view user profiles (Confluence admin, or grant 'View user profiles' global permission)","If the instance enforces SSO, create and use a Personal Access Token (Server 7.9+) instead of basic auth","Check any reverse proxy/WAF in front of Confluence for 403 rules on rest/api/user/current","Catch ApiPermissionError where user-email enrichment is optional, and degrade to indexing without emails instead of failing the run"],"exampleFix":"// before\nresponse = confluence_client.get_mobile_parameters(user_name)\nemail = response.get('email')\n// after\nfrom atlassian.errors import ApiPermissionError\ntry:\n    response = confluence_client.get_mobile_parameters(user_name)\n    email = response.get('email')\nexcept ApiPermissionError:\n    logging.warning('no profile-view permission; indexing without email for %s', user_name)\n    email = None","handlingStrategy":"try-catch","validationCode":"# preflight: confirm the token can view profiles before enrichment runs\nresp = confluence_client.get('rest/api/user/current')\nif resp is None:\n    disable_email_enrichment = True","typeGuard":null,"tryCatchPattern":"from atlassian.errors import ApiPermissionError\ntry:\n    email = get_user_email_from_username__server(client, user_name)\nexcept ApiPermissionError:\n    logging.warning('profile view denied; continuing without email for %s', user_name)\n    email = None","preventionTips":["Treat email enrichment as optional: catch ApiPermissionError at the call site and index without emails rather than failing the run","Use a PAT from a user with profile-view permission on Confluence Server, and confirm the proxy in front of Confluence does not 403 the indexing host"],"tags":["confluence","permissions","http-403","server"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}