{"record":{"id":"4db1d58eb0818a69","repo":"infiniflow/ragflow","slug":"jira-validation-failed-message","errorCode":null,"errorMessage":"Jira validation failed: {message}","messagePattern":"Jira validation failed: (.+?)","errorType":"validation","errorClass":"ConnectorValidationError","httpStatus":null,"severity":"error","filePath":"common/data_source/jira/connector.py","lineNumber":293,"sourceCode":"                    continue\n                raise\n\n    def _handle_validation_error(self, exc: Exception) -> None:\n        status_code = getattr(exc, \"status_code\", None)\n        if status_code == 401:\n            raise InsufficientPermissionsError(\"Jira credential appears to be invalid or expired (HTTP 401).\") from exc\n        if status_code == 403:\n            raise InsufficientPermissionsError(\"Jira token does not have permission to access the requested resources (HTTP 403).\") from exc\n        if status_code == 404:\n            raise ConnectorValidationError(\"Jira resource not found (HTTP 404).\") from exc\n        if status_code == 429:\n            raise ConnectorValidationError(\"Jira rate limit exceeded during validation (HTTP 429).\") from exc\n\n        message = getattr(exc, \"text\", str(exc))\n        if not message:\n            raise UnexpectedValidationError(\"Unexpected Jira validation error.\") from exc\n\n        raise ConnectorValidationError(f\"Jira validation failed: {message}\") from exc\n\n    def _load_from_checkpoint_internal(\n        self,\n        jql: str,\n        checkpoint: JiraCheckpoint,\n        start_filter: SecondsSinceUnixEpoch | None = None,\n    ) -> Generator[Document | ConnectorFailure, None, JiraCheckpoint]:\n        assert self.jira_client, \"load_credentials must be called before loading issues.\"\n\n        page_size = self._full_page_size()\n        new_checkpoint = copy.deepcopy(checkpoint)\n        starting_offset = new_checkpoint.start_at or 0\n        current_offset = starting_offset\n        checkpoint_callback = self._make_checkpoint_callback(new_checkpoint)\n\n        issue_iter = self._perform_jql_search(\n            jql=jql,\n            start=current_offset,","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/jira/connector.py#L275-L311","documentation":"Thrown by the Jira connector's validate_connector_settings as a ConnectorValidationError when the Jira HTTP request fails with a status code not explicitly mapped (i.e. not 401/403/404/429) and the response body contains some text. The message interpolates the raw response text from the exception, so the upstream Jira server error is surfaced verbatim. It is the catch-all 'other HTTP error' branch of credential validation.","triggerScenarios":"Calling connector.validate_connector_settings() (directly or via load_credentials-driven validation flows) when the Jira REST API returns any non-2xx status other than 401/403/404/429 with a non-empty body — e.g. 400 Bad Request from a malformed base_url, 500/502/503 from Jira, or a proxy returning an HTML error page with a status like 502.","commonSituations":"Misconfigured base_url pointing to a load balancer or SSO gateway that returns 4xx/5xx; Jira Cloud/Data Center outage or maintenance window returning 503; corporate proxy intercepting the request; auth scheme mismatch (scoped token vs basic auth) producing 400.","solutions":["Inspect the interpolated {message} text — it is the raw response body from Jira and names the real problem (e.g. 'XSRF check failed', '502 Bad Gateway').","If the message mentions gateway/proxy/502/503, verify base_url points directly at the Jira instance REST endpoint (e.g. https://yourorg.atlassian.net) and retry once the service is back.","If it is a 400-class message, check credential shape: API token with email, or scoped token configured correctly; confirm no stale cookies/headers are injected by a proxy.","Reproduce with curl -u email:token <base_url>/rest/api/2/myself to see the exact status and body outside the connector."],"exampleFix":"# before\nconnector.load_credentials({\"jira_user_email\": email, \"jira_api_token\": token})\nconnector.validate_connector_settings()  # raises ConnectorValidationError('Jira validation failed: ...')\n\n# after\nfrom onyx.configs.constants import ...  # adjust import to your tree\ntry:\n    connector.validate_connector_settings()\nexcept ConnectorValidationError as exc:\n    logging.error(\"Jira validation failed: %s\", exc)\n    raise","handlingStrategy":"try-catch","validationCode":"import requests\n\ndef jira_reachable(base_url: str, email: str, token: str) -> bool:\n    r = requests.get(f\"{base_url}/rest/api/2/myself\", auth=(email, token), timeout=10)\n    return r.status_code == 200","typeGuard":null,"tryCatchPattern":"try:\n    connector.validate_connector_settings()\nexcept InsufficientPermissionsError:\n    ...  # 401/403: credential problem\nexcept ConnectorValidationError as exc:\n    # includes 'Jira validation failed: {message}' catch-all\n    log_and_surface(str(exc))","preventionTips":["Smoke-test credentials with a single GET /rest/api/2/myself before wiring the full connector.","Keep base_url pointed directly at the Jira origin, not an SSO/proxy hop.","Handle mapped statuses (401/403/404/429) distinctly; the catch-all text is the raw body — log it in full."],"tags":["jira","http","validation","connector","credentials"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}