{"record":{"id":"4040dbf302d3b31d","repo":"infiniflow/ragflow","slug":"github","errorCode":null,"errorMessage":"GitHub","messagePattern":"GitHub","errorType":"validation","errorClass":"ConnectorMissingCredentialError","httpStatus":null,"severity":"error","filePath":"common/data_source/github/connector.py","lineNumber":445,"sourceCode":"        except RateLimitExceededException:\n            sleep_after_rate_limit_exception(github_client)\n            return self.get_all_repos(github_client, attempt_num + 1)\n\n    def _pull_requests_func(self, repo: Repository.Repository) -> Callable[[], PaginatedList[PullRequest]]:\n        return lambda: repo.get_pulls(state=self.state_filter, sort=\"updated\", direction=\"desc\")\n\n    def _issues_func(self, repo: Repository.Repository) -> Callable[[], PaginatedList[Issue]]:\n        return lambda: repo.get_issues(state=self.state_filter, sort=\"updated\", direction=\"desc\")\n\n    def _fetch_from_github(\n        self,\n        checkpoint: GithubConnectorCheckpoint,\n        start: datetime | None = None,\n        end: datetime | None = None,\n        include_permissions: bool = False,\n    ) -> Generator[Document | ConnectorFailure, None, GithubConnectorCheckpoint]:\n        if self.github_client is None:\n            raise ConnectorMissingCredentialError(\"GitHub\")\n\n        checkpoint = copy.deepcopy(checkpoint)\n\n        # First run of the connector, fetch all repos and store in checkpoint\n        if checkpoint.cached_repo_ids is None:\n            repos = []\n            if self.repositories:\n                if \",\" in self.repositories:\n                    # Multiple repositories specified\n                    repos = self.get_github_repos(self.github_client)\n                else:\n                    # Single repository (backward compatibility)\n                    repos = [self.get_github_repo(self.github_client)]\n            else:\n                # All repositories\n                repos = self.get_all_repos(self.github_client)\n            if not repos:\n                checkpoint.has_more = False","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/github/connector.py#L427-L463","documentation":"The GitHub connector's core fetch generator _fetch_from_github raises ConnectorMissingCredentialError('GitHub') when self.github_client is None. Every checkpointed run funnels through this method, so the error means the run began without a constructed Github() client — i.e. load_credentials() did not run or did not reach github.Github(...). It fires before the checkpoint deep-copy and any API call.","triggerScenarios":"Invoking load_from_checkpoint / load_from_checkpoint_with_perm_sync (both call _fetch_from_github) on a connector whose load_credentials was never called, so github_client stayed None.","commonSituations":"Indexing worker building the connector but the credential payload lacked the GitHub access token; misconfigured credential store; running the connector in a script/test without the credential bootstrap step.","solutions":["Call connector.load_credentials({... 'github_access_token': ...}) before load_from_checkpoint*.","Verify the credential document actually contains a non-empty github_access_token; log its presence (not value) at startup.","Wire validate_connector_settings() into run startup so missing credentials fail fast with a clear message instead of mid-generator."],"exampleFix":"// before\nconnector = GithubConnector(...)\nfor doc in connector.load_from_checkpoint(start, end, checkpoint):\n    ...  # raises ConnectorMissingCredentialError('GitHub')\n\n# after\nconnector = GithubConnector(...)\nconnector.load_credentials({'github_access_token': token, ...})\nfor doc in connector.load_from_checkpoint(start, end, checkpoint):\n    ...","handlingStrategy":"validation","validationCode":"if connector.github_client is None:\n    raise RuntimeError('GitHub credentials not loaded before checkpoint run')","typeGuard":"def has_github_client(c: GithubConnector) -> bool:\n    return c.github_client is not None","tryCatchPattern":"try:\n    for doc in connector.load_from_checkpoint(start, end, cp):\n        ...\nexcept ConnectorMissingCredentialError:\n    # credential bootstrap failed; do not retry the run as-is\n    reload_credentials_and_restart(connector)","preventionTips":["Call load_credentials before every load_from_checkpoint run.","Log credential presence (not value) at worker startup to catch missing tokens early."],"tags":["github","credentials","connector","checkpoint"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}