{"record":{"id":"89ee600228023394","repo":"FoundationAgents/MetaGPT","slug":"access-token-is-invalid-visit-https-github","errorCode":null,"errorMessage":"`access_token` is invalid. Visit: \"https://github.com/settings/tokens\"","messagePattern":"`access_token` is invalid\\. Visit: \"https://github\\.com/settings/tokens\"","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"metagpt/utils/git_repository.py","lineNumber":273,"sourceCode":"            new_branch (str): The name of the new branch to be pushed.\n            comments (str, optional): Comments to be associated with the push. Defaults to \"Archive\".\n            access_token (str, optional): Access token for authentication. Defaults to None. Visit `https://pygithub.readthedocs.io/en/latest/examples/Authentication.html`, `https://github.com/PyGithub/PyGithub/blob/main/doc/examples/Authentication.rst`.\n            auth (Auth, optional): Optional authentication object. Defaults to None.\n\n        Returns:\n            GitBranch: The pushed branch object.\n\n        Raises:\n            ValueError: If neither `auth` nor `access_token` is provided.\n            BadCredentialsException: If authentication fails due to bad credentials or timeout.\n\n        Note:\n            This function assumes that `self.current_branch`, `self.new_branch()`, `self.archive()`,\n            `ctx.config.proxy`, `ctx.config`, `self.remote_url`, `shell_execute()`, and `logger` are\n            defined and accessible within the scope of this function.\n        \"\"\"\n        if not auth and not access_token:\n            raise ValueError('`access_token` is invalid. Visit: \"https://github.com/settings/tokens\"')\n        from metagpt.context import Context\n\n        base = self.current_branch\n        head = base if not new_branch else self.new_branch(new_branch)\n        self.archive(comments)  # will skip committing if no changes\n        ctx = Context()\n        env = ctx.new_environ()\n        proxy = [\"-c\", f\"http.proxy={ctx.config.proxy}\"] if ctx.config.proxy else []\n        token = access_token or auth.token\n        remote_url = f\"https://{token}@\" + self.remote_url.removeprefix(\"https://\")\n        command = [\"git\"] + proxy + [\"push\", remote_url]\n        logger.info(\" \".join(command).replace(token, \"<TOKEN>\"))\n        try:\n            stdout, stderr, return_code = await shell_execute(\n                command=command, cwd=str(self.workdir), env=env, timeout=15\n            )\n        except TimeoutExpired as e:\n            info = str(e).replace(token, \"<TOKEN>\")","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/utils/git_repository.py#L255-L291","documentation":"Raised by GitRepository.push() (metagpt/utils/git_repository.py:273): the method needs credentials to push and neither the `auth` object nor the `access_token` string argument was supplied. It deliberately fails before running any git command so tokens are never taken from thin air.","triggerScenarios":"Calling repo.push(new_branch='feat', comments='...') with no access_token and no auth argument. The token cannot be inferred from the repository URL or global config at this point.","commonSituations":"Automation/agent runs (e.g. after DocumentGenerator or code generation) that expect a GitHub token from the environment but none was configured; scripts migrated from an older version that read METAGPT_GIT_TOKEN implicitly.","solutions":["Pass a GitHub personal access token: repo.push(new_branch='x', comments='y', access_token=os.environ['GITHUB_TOKEN']).","Or pass a PyGithub Auth object via the auth parameter.","Create the token at https://github.com/settings/tokens with repo scope and store it in an env var / devkey rather than in code."],"exampleFix":"# before\nrepo.push(new_branch='feature', comments='update')  # ValueError\n\n# after\nimport os\nrepo.push(new_branch='feature', comments='update', access_token=os.environ['METAGPT_GIT_TOKEN'])","handlingStrategy":"validation","validationCode":"import os\ntoken = os.environ.get('METAGPT_GIT_TOKEN') or os.environ.get('GITHUB_TOKEN')\nif not token:\n    raise SystemExit('Set METAGPT_GIT_TOKEN to enable git push')","typeGuard":"def can_push(access_token: str | None, auth) -> bool:\n    return bool(access_token or auth)","tryCatchPattern":"try:\n    repo.push(new_branch=branch, comments=msg, access_token=token)\nexcept ValueError as e:\n    if 'access_token' in str(e):\n        logger.error('No git credentials configured; push skipped')","preventionTips":["Store the PAT in an env var or devkey and always pass it explicitly.","Fail fast at process start if push is expected but no token is present.","Give the token repo scope and an expiry; rotate regularly."],"tags":["git","auth","github","push"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}