{"record":{"id":"01f4ec677483367a","repo":"infiniflow/ragflow","slug":"dropbox","errorCode":null,"errorMessage":"Dropbox","messagePattern":"Dropbox","errorType":"validation","errorClass":"ConnectorMissingCredentialError","httpStatus":null,"severity":"error","filePath":"common/data_source/dropbox_connector.py","lineNumber":43,"sourceCode":"    \"\"\"Dropbox connector for accessing Dropbox files and folders\"\"\"\n\n    def __init__(self, batch_size: int = INDEX_BATCH_SIZE) -> None:\n        self.batch_size = batch_size\n        self.dropbox_client: Dropbox | None = None\n\n    def load_credentials(self, credentials: dict[str, Any]) -> dict[str, Any] | None:\n        \"\"\"Load Dropbox credentials\"\"\"\n        access_token = credentials.get(\"dropbox_access_token\")\n        if not access_token:\n            raise ConnectorMissingCredentialError(\"Dropbox access token is required\")\n\n        self.dropbox_client = Dropbox(access_token)\n        return None\n\n    def validate_connector_settings(self) -> None:\n        \"\"\"Validate Dropbox connector settings\"\"\"\n        if self.dropbox_client is None:\n            raise ConnectorMissingCredentialError(\"Dropbox\")\n\n        try:\n            self.dropbox_client.files_list_folder(path=\"\", limit=1)\n        except AuthError as e:\n            logger.exception(\"[Dropbox]: Failed to validate Dropbox credentials\")\n            raise ConnectorValidationError(f\"Dropbox credential is invalid: {e}\")\n        except ApiError as e:\n            if e.error is not None and \"insufficient_permissions\" in str(e.error).lower():\n                raise InsufficientPermissionsError(\"Your Dropbox token does not have sufficient permissions.\")\n            raise ConnectorValidationError(f\"Unexpected Dropbox error during validation: {e.user_message_text or e}\")\n        except Exception as e:\n            raise ConnectorValidationError(f\"Unexpected error during Dropbox settings validation: {e}\")\n\n    def _download_file(self, path: str) -> bytes:\n        \"\"\"Download a single file from Dropbox.\"\"\"\n        if self.dropbox_client is None:\n            raise ConnectorMissingCredentialError(\"Dropbox\")\n        _, resp = self.dropbox_client.files_download(path)","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/dropbox_connector.py#L25-L61","documentation":"Raised by validate_connector_settings() when self.dropbox_client is None — i.e. validate was called before load_credentials successfully built the Dropbox SDK client. Immediate guard before the files_list_folder probe.","triggerScenarios":"Constructing DropboxConnector and calling validate_connector_settings() without load_credentials; a prior load_credentials raised ConnectorMissingCredentialError and the caller continued.","commonSituations":"Health-check endpoints validating connectors that were never credentialed; UI validate-before-save flows.","solutions":["Always run load_credentials(...) successfully before validate_connector_settings()","Treat a None dropbox_client as 'not configured' in orchestration code and skip validation","Do not reuse a connector instance after a failed load_credentials"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if connector.dropbox_client is None:\n    connector.load_credentials({'dropbox_access_token': token})","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Combine construction and credential loading in one factory function","Surface 'not configured' state in UI instead of invoking validation"],"tags":["dropbox","credentials","lifecycle","validation"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}