{"record":{"id":"693df0b7bb9d0c3d","repo":"infiniflow/ragflow","slug":"dingtalk-access-token-not-loaded","errorCode":null,"errorMessage":"DingTalk access_token not loaded","messagePattern":"DingTalk access_token not loaded","errorType":"validation","errorClass":"ConnectorMissingCredentialError","httpStatus":null,"severity":"error","filePath":"common/data_source/dingtalk_ai_table_connector.py","lineNumber":117,"sourceCode":"        if not access_token:\n            raise ConnectorMissingCredentialError(\"DingTalk access_token is required\")\n\n        self._access_token = access_token\n        self._client = self._create_client()\n        return None\n\n    @property\n    def client(self) -> NotableClient:\n        \"\"\"Get the DingTalk AITable client.\"\"\"\n        if self._client is None:\n            raise DingTalkAITableClientNotSetUpError()\n        return self._client\n\n    @property\n    def access_token(self) -> str:\n        \"\"\"Get the access token.\"\"\"\n        if self._access_token is None:\n            raise ConnectorMissingCredentialError(\"DingTalk access_token not loaded\")\n        return self._access_token\n\n    def validate_connector_settings(self) -> None:\n        \"\"\"Validate DingTalk connector settings by trying to get all sheets.\"\"\"\n        if self._client is None or self._access_token is None:\n            raise ConnectorMissingCredentialError(\"DingTalk Notable\")\n\n        try:\n            # Try to get sheets to validate credentials\n            headers = notable_models.GetAllSheetsHeaders()\n            headers.x_acs_dingtalk_access_token = self._access_token\n\n            request = notable_models.GetAllSheetsRequest(\n                operator_id=self.operator_id,\n            )\n\n            self.client.get_all_sheets_with_options(\n                self.table_id,","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/dingtalk_ai_table_connector.py#L99-L135","documentation":"Raised by the access_token property when self._access_token is None, i.e. the property was read before load_credentials() stored the token. Unlike the load-time check (which validates the input dict), this fires on the read path whenever any method needs the token and it was never loaded.","triggerScenarios":"Calling _get_all_sheets or other indexing methods on a freshly constructed connector without load_credentials(); an earlier load_credentials call raised and the connector was reused anyway.","commonSituations":"Test code that skips credential setup; orchestrators that catch the load error but proceed to poll_source/load_from_state.","solutions":["Call load_credentials(...) successfully before any indexing or validate call","If load_credentials raised, do not reuse the instance; rebuild it","In orchestrating code, treat ConnectorMissingCredentialError as fatal for that run, not retriable"],"exampleFix":"// before\nconnector = DingTalkAITableConnector(...)\nsheets = connector._get_all_sheets()  # raises\n\n// after\nconnector.load_credentials({'access_token': token})\nsheets = connector._get_all_sheets()","handlingStrategy":"validation","validationCode":"if connector._access_token is None:\n    connector.load_credentials({'access_token': fetch_token()})","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat load_credentials as mandatory constructor step 2; wrap construction+loading in one factory function","Never reuse a connector instance whose load_credentials raised"],"tags":["dingtalk","credentials","lifecycle"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}