Skip to content

Commit 61e98e8

Browse files
Sai Sridharclaude
andcommitted
Fix Gmail sync 403: fall back to labelIds when metadata scope blocks q param
Unverified OAuth app gets gmail.metadata only, not gmail.readonly. gmail.metadata scope doesn't support the q search parameter. Catch 403 + retry with labelIds=['INBOX'] instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 67fae10 commit 61e98e8

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

backend/services/gmail_service.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,26 @@ async def fetch_new_emails(user_id: str) -> list[dict]:
414414

415415
service = build("gmail", "v1", credentials=creds, cache_discovery=False)
416416

417-
list_result = (
418-
service.users()
419-
.messages()
420-
.list(userId="me", q=gmail_query, maxResults=max_results)
421-
.execute()
422-
)
417+
try:
418+
list_result = (
419+
service.users()
420+
.messages()
421+
.list(userId="me", q=gmail_query, maxResults=max_results)
422+
.execute()
423+
)
424+
except HttpError as exc:
425+
if exc.resp.status == 403 and "Metadata scope" in str(exc):
426+
# gmail.metadata scope doesn't support q — fall back to labelIds
427+
logger.warning("Falling back to labelIds for user_id=%s (metadata scope only)", user_id)
428+
list_result = (
429+
service.users()
430+
.messages()
431+
.list(userId="me", labelIds=["INBOX"], maxResults=max_results)
432+
.execute()
433+
)
434+
else:
435+
raise
436+
423437
message_refs = list_result.get("messages", [])
424438

425439
if not message_refs:

0 commit comments

Comments
 (0)