{"record":{"id":"40af81466dc7d05d","repo":"infiniflow/ragflow","slug":"exc","errorCode":null,"errorMessage":"{exc}","messagePattern":"\\{exc\\}","errorType":"validation","errorClass":"ConnectorValidationError","httpStatus":null,"severity":"error","filePath":"common/data_source/jira/connector.py","lineNumber":146,"sourceCode":"            try:\n                buffer_value = int(time_buffer_seconds)\n            except (TypeError, ValueError) as exc:\n                raise ConnectorValidationError(f\"Invalid time_buffer_seconds value ({time_buffer_seconds!r}); expected an integer.\") from exc\n        self.time_buffer_seconds = max(0, buffer_value)\n\n    # -------------------------------------------------------------------------\n    # Connector lifecycle helpers\n    # -------------------------------------------------------------------------\n\n    def load_credentials(self, credentials: dict[str, Any]) -> dict[str, Any] | None:\n        \"\"\"Instantiate the Jira client using either an API token or username/password.\"\"\"\n        jira_url_for_client = self.jira_base_url\n        if self.scoped_token:\n            if is_atlassian_cloud_url(self.jira_base_url):\n                try:\n                    jira_url_for_client = scoped_url(self.jira_base_url, \"jira\")\n                except ValueError as exc:\n                    raise ConnectorValidationError(str(exc)) from exc\n            else:\n                logger.warning(\"[Jira] Scoped token requested but Jira base URL does not appear to be an Atlassian Cloud domain; scoped token ignored.\")\n\n        user_email = credentials.get(\"jira_user_email\") or credentials.get(\"jira_username\")\n        api_token = credentials.get(\"jira_api_token\") or credentials.get(\"token\") or credentials.get(\"api_token\")\n        password = credentials.get(\"jira_password\") or credentials.get(\"password\")\n        rest_api_version = credentials.get(\"rest_api_version\")\n\n        if not rest_api_version:\n            rest_api_version = JIRA_CLOUD_API_VERSION if api_token else JIRA_SERVER_API_VERSION\n        options: dict[str, Any] = {\"rest_api_version\": rest_api_version}\n\n        try:\n            if user_email and api_token:\n                self.jira_client = JIRA(\n                    server=jira_url_for_client,\n                    basic_auth=(user_email, api_token),\n                    options=options,","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/jira/connector.py#L128-L164","documentation":"ConnectorValidationError whose message is the str() of an underlying ValueError from scoped_url(jira_base_url, 'jira'). This path only runs when scoped_token=True and the base URL passes is_atlassian_cloud_url; scoped_url then tries to derive the product-scoped URL (e.g. https://yourcompany.atlassian.net/jira) and fails, typically because the URL is malformed or already contains a path.","triggerScenarios":"scoped_token=True with a base URL like 'https://yourcompany.atlassian.net/', 'https://host//jira', or a URL the cloud check lets through but the parser rejects (bad scheme, embedded path, whitespace).","commonSituations":"Enabling scoped-token support for Atlassian guard-style setups; URLs pasted with trailing slashes or a pre-appended /jira path; normalizing logic elsewhere in the pipeline mangling the URL before it reaches the connector.","solutions":["Pass a clean origin URL: scheme plus host only, no path, no trailing slash - e.g. 'https://yourcompany.atlassian.net'.","Strip whitespace and trailing '/' before constructing the connector (the constructor rstrips after this check, so pre-clean).","Read the wrapped ValueError text - it states exactly what scoped_url disliked about the URL."],"exampleFix":"# before\nJiraConnector(jira_base_url='https://acme.atlassian.net/', scoped_token=True)  # -> str(ValueError from scoped_url)\n\n# after\nJiraConnector(jira_base_url='https://acme.atlassian.net', scoped_token=True)","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\n\ndef clean_origin(url: str) -> str:\n    p = urlparse(url.strip())\n    return f'{p.scheme}://{p.netloc}'","typeGuard":null,"tryCatchPattern":"try:\n    connector = JiraConnector(jira_base_url=raw_url, scoped_token=True)\nexcept ConnectorValidationError as e:\n    if 'url' in str(e).lower():\n        connector = JiraConnector(jira_base_url=clean_origin(raw_url), scoped_token=True)\n    else:\n        raise","preventionTips":["Store only scheme plus host for Jira base URLs; never include product paths or trailing slashes.","Add a URL normalization step in the config pipeline for all connector URLs.","The wrapped ValueError text states the exact defect - always read it before changing code."],"tags":["jira","validation","url","scoped-token"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}