{"record":{"id":"0c17c99b2ec680d7","repo":"infiniflow/ragflow","slug":"jira","errorCode":null,"errorMessage":"Jira","messagePattern":"Jira","errorType":"validation","errorClass":"ConnectorMissingCredentialError","httpStatus":null,"severity":"error","filePath":"common/data_source/jira/connector.py","lineNumber":188,"sourceCode":"                    options=options,\n                )\n            elif user_email and password:\n                self.jira_client = JIRA(\n                    server=jira_url_for_client,\n                    basic_auth=(user_email, password),\n                    options=options,\n                )\n            else:\n                raise ConnectorMissingCredentialError(\"Jira credentials must include either an API token or username/password.\")\n        except Exception as exc:  # pragma: no cover - jira lib raises many types\n            raise ConnectorMissingCredentialError(f\"Jira: {exc}\") from exc\n        self._sync_timezone_from_server()\n        return None\n\n    def validate_connector_settings(self) -> None:\n        \"\"\"Validate connectivity by fetching basic Jira info.\"\"\"\n        if not self.jira_client:\n            raise ConnectorMissingCredentialError(\"Jira\")\n\n        try:\n            if self.jql_query:\n                dummy_checkpoint = self.build_dummy_checkpoint()\n                checkpoint_callback = self._make_checkpoint_callback(dummy_checkpoint)\n                iterator = self._perform_jql_search(\n                    jql=self.jql_query,\n                    start=0,\n                    max_results=1,\n                    fields=\"key\",\n                    all_issue_ids=dummy_checkpoint.all_issue_ids,\n                    checkpoint_callback=checkpoint_callback,\n                    next_page_token=dummy_checkpoint.cursor,\n                    ids_done=dummy_checkpoint.ids_done,\n                )\n                next(iter(iterator), None)\n            elif self.project_key:\n                self.jira_client.project(self.project_key)","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/jira/connector.py#L170-L206","documentation":"ConnectorMissingCredentialError('Jira') raised at the top of validate_connector_settings when self.jira_client is still None - i.e. validate_connector_settings() was called before load_credentials() successfully created the client. The bare 'Jira' message identifies the connector, not a specific failure; it is purely a lifecycle-order error.","triggerScenarios":"Constructing JiraConnector and immediately calling validate_connector_settings() without an intervening load_credentials(); or a prior load_credentials that raised, leaving jira_client unset, followed by a catch-all that still runs validation.","commonSituations":"Orchestration code that validates all connectors in a loop regardless of whether credential loading succeeded; refactors that reordered lifecycle calls; retry paths that skip the credential step.","solutions":["Call load_credentials(creds) and let it return before calling validate_connector_settings().","If load_credentials raised, do not proceed to validation - propagate the error instead.","Guard with a check of connector.jira_client in generic orchestration code and load credentials first."],"exampleFix":"# before\nconnector = JiraConnector(jira_base_url=url)\nconnector.validate_connector_settings()  # ConnectorMissingCredentialError('Jira')\n\n# after\nconnector = JiraConnector(jira_base_url=url)\nconnector.load_credentials(creds)\nconnector.validate_connector_settings()","handlingStrategy":"validation","validationCode":"def jira_connector_ready(connector) -> bool:\n    return connector.jira_client is not None","typeGuard":null,"tryCatchPattern":"try:\n    connector.validate_connector_settings()\nexcept ConnectorMissingCredentialError:\n    if connector.jira_client is None:\n        raise RuntimeError('Call load_credentials() before validate_connector_settings()')\n    raise","preventionTips":["Enforce construct -> load_credentials -> validate ordering in one orchestration function.","Never continue past a failed load_credentials; abort the task instead.","Write a lifecycle unit test that asserts validation fails with a clear error when credentials are skipped."],"tags":["jira","lifecycle","credentials","connector"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}