From 9fe8e865c4c98b0171d18fee442ebc0301adb3f6 Mon Sep 17 00:00:00 2001 From: Serge Rabyking Date: Thu, 30 Apr 2026 08:48:30 +0200 Subject: [PATCH] fix(auth): suggest fix when gh token is missing user:email scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the chipflow API rejects /auth/github-token with {"error":"missing_email", ...}, it means the gh CLI token is missing the user:email scope and the server can't fetch a verified email. Previously the lib just printed the generic "GitHub token authentication failed: ..." message and silently fell through to device flow (which then expires in non-interactive contexts). The user had no signal that their gh token needs a one-line refresh. Now we detect the specific error code and print: šŸ’” Your `gh` CLI token is missing the `user:email` scope. Run this once and retry: gh auth refresh -s user:email --- chipflow/auth.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/chipflow/auth.py b/chipflow/auth.py index dcbe3b32..0b7dd74e 100644 --- a/chipflow/auth.py +++ b/chipflow/auth.py @@ -135,14 +135,27 @@ def authenticate_with_github_token(api_origin: str, interactive: bool = True): logger.debug(f"Invalid JSON response on success: {e}, body: {response.text[:200]}") return None else: + error_code = "" try: - error_msg = response.json().get("error_description", "Unknown error") + body = response.json() + error_code = body.get("error", "") + error_msg = body.get("error_description", "Unknown error") except ValueError: error_msg = f"HTTP {response.status_code}" logger.debug(f"Non-JSON error response: {response.text[:200]}") if interactive: print(f"āš ļø GitHub token authentication failed: {error_msg}") + if error_code == "missing_email": + # The server fetched the gh token but couldn't read the + # user's email — the token is missing the user:email + # scope. Tell the user the exact command to fix it, + # otherwise they fall through to device flow with no clue. + print( + "\nšŸ’” Your `gh` CLI token is missing the `user:email` scope.\n" + " Run this once and retry:\n" + " gh auth refresh -s user:email" + ) logger.debug(f"GitHub token auth failed: {response.status_code} - {error_msg}") return None