Skip to content

fix(knowledge): treat Google Workspace users without Gmail or Calendar as out of scope, not listing failures - #8168

Merged
waleedlatif1 merged 3 commits into
stagingfrom
fix/google-workspace-unlicensed-users
Sep 22, 2026
Merged

waleedlatif1 merged 3 commits into
stagingfrom
fix/google-workspace-unlicensed-users

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Admin-mode Gmail and Calendar recorded Directory users with no mailbox, and a Calendar 403 notACalendarUser, as per-user listing failures. Those partitions stayed blocked, so remaining() never reached zero, hasMore stayed true, and the listing never reached its end: reconcileCompletedListing was never called, the connector stayed partial, and the same accounts were re-probed every retry window
  • A service-not-enabled answer (no mailbox, or a calendar.events.list 403 whose only reason is notACalendarUser) is now a skip only on the user's first provider page, and only when readers see none of that user's documents from this connector or the condition was first observed at least 24 h ago (Google applies service and organizational-unit changes within 24 h). A skipped user's partition completes with no failure and is re-probed no sooner than the Directory refresh
  • Otherwise it stays a retained failure, as before, with its first observation kept in the partition's failure (since). The documents are not reconciled until 24 h have passed. A mid-listing answer is always a retained failure; once it has lasted 24 h the user restarts from their first page
  • Permission passes skip on the first page, since a retained failure refreshes no permissions either
  • Gmail Directory enumeration drops a user without a mailbox (like an inactive user) unless readers still see their mail; the hourly refresh picks them up once provisioned. The crawl reports a missing mailbox to the scheduler instead of recording its own failure
  • Bare forbidden, mixed-reason, and incomplete-reason Calendar 403s stay retryable failures
  • "Readers still see" means a live, non-excluded document in this connector granted to u:<email> with permission evidence inside the existing 24 h freshness limit. It is read through doc_acl_gin_idx behind an OFFSET 0 fence, so the cost is bounded by that user's grants, not the connector's size

Type of Change

  • Bug fix

Testing

  • Extended company-crawl.test.ts and google-company-scheduler.test.ts. They cover:
    • users with visible documents inside and past the 24 h window, for Gmail and Calendar
    • users with no visible documents skipped immediately
    • Gmail Directory enumeration with and without visible mail
    • a mid-listing answer
    • permission passes
  • Each guard was mutated separately (first-page check, persistence window, visibility check, since carry, mid-listing reset, permission skip, Directory visibility check, crawl mailbox signal), and each turned its tests red
  • lib/knowledge + connectors suites pass; bun run lint, bun run check:audits, and apps/sim type-check pass

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…r as out of scope, not listing failures

Admin-mode Gmail recorded a Directory user without a mailbox, and Calendar recorded a
403 notACalendarUser, as per-user listing failures. Both are standing account properties,
so the connector stayed partial, deletion reconciliation never ran, and the scheduler
re-probed the same accounts every retry window.

- Directory enumeration no longer schedules Gmail users whose mailbox is not set up; the
  hourly Directory refresh picks them up once provisioned. A partition queued earlier
  completes with an empty page instead of a failure.
- A Calendar 403 whose only reason is notACalendarUser completes the user's partition
  cleanly and re-probes it no sooner than the Directory refresh (permissions keep their
  own refresh cadence). Bare forbidden and mixed-reason 403s stay retryable failures.
@vercel

vercel Bot commented Sep 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
docs Ready Ready Preview Sep 22, 2026 10:44pm UTC

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/connectors/google-workspace/company-crawl.ts
@greptile-apps

greptile-apps Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge, with the revised service-not-enabled lifecycle preserving reconciliation safety and eventually completing out-of-scope user partitions.

Summary

This PR changes admin-mode Gmail and Google Calendar synchronization so accounts without the corresponding service can complete as out of scope instead of permanently blocking connector reconciliation.

  • Recognizes narrowly defined Gmail mailbox and Calendar service-not-enabled conditions.
  • Retains existing visible documents during Google's 24-hour service-change propagation window.
  • Persists the first observation time across partition retries and safely restarts mid-listing users.
  • Adds an indexed visibility probe and integration coverage for its document-state and ACL-freshness filters.
  • Adds scheduler and crawl coverage for first-page, mid-listing, permission-refresh, and Directory-refresh behavior.
  • Registers the new PostgreSQL integration test in CI.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  D[Directory user] --> E{Gmail mailbox present?}
  E -->|Yes or Calendar| P[Run provider listing]
  E -->|No| V{Fresh visible documents?}
  V -->|No| O[Leave user out of scope]
  V -->|Yes| P
  P --> S{Service-not-enabled response?}
  S -->|No| N[Normal page or retained provider failure]
  S -->|Yes| F{First provider page?}
  F -->|No| R[Retain failure and preserve since]
  F -->|Yes| W{Permission pass, no visible docs, or persisted 24h?}
  W -->|No| R
  W -->|Yes| C[Complete partition without listing failure]
  R --> T{Persisted 24h?}
  T -->|No| R
  T -->|Yes| X[Reset to first page]
  X --> C
  C --> Q[Re-probe at scheduled refresh]
Loading

Reviews (2) · Last reviewed commit: "fix(knowledge): read a user's visible do..."

…l a missing service outlasts propagation

Google applies service and organizational-unit changes within 24 hours, so a missing
mailbox or notACalendarUser can be transient for a user whose documents are already
indexed, and a mid-listing answer does not prove the whole account lacks the service.

- The scheduler skips a service-not-enabled user only on their first provider page, and
  only when readers see none of their documents or the condition was first observed at
  least 24 hours ago. Otherwise it is a retained failure, as before, whose first
  observation is kept in the partition failure; after 24 hours a mid-listing user
  restarts from their first page.
- Permission passes skip on the first page, since a retained failure refreshes nothing.
- Gmail Directory enumeration keeps scheduling a user without a mailbox while readers
  still see their mail; the crawl reports the missing mailbox to the scheduler instead of
  completing the user.
- Visibility is read through doc_acl_gin_idx for the user's token behind an OFFSET 0
  fence, bounded by that user's grants.
…d cover the probe in PostgreSQL

The visibility probe moves to its own module so it can run against a real database.
Planned inline, LIMIT 1 made a sequential scan of the document table look cheaper than
doc_acl_gin_idx, because PostgreSQL cannot estimate array overlap. A materialized CTE now
reads the user's grants from the index first, bounding the probe by that user's grants.
The email goes through userToken, so a mixed-case or padded directory address matches the
normalized ACL token.

The new PostgreSQL integration test covers fresh, stale and missing permission evidence,
another user's grant, another connector, excluded, archived and deleted documents, and
email normalization, and runs in the Search progress PostgreSQL CI step.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 12 files

Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.

Re-trigger cubic

@waleedlatif1
waleedlatif1 merged commit b44596f into staging Sep 22, 2026
34 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/google-workspace-unlicensed-users branch September 23, 2026 00:05

This branch was successfully deployed

1 active deployment
Preview 4c785f0a Deployed Sep 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant