fix: surface an unbilled run, and clamp the google-docs page cap - #7025
Conversation
Two places where a failure is reported as something smaller than it is.
**A run that is never billed logs as a notification problem.** The usage
safety net re-records billing when an earlier step threw before the single
record call, and its own failure went into a bare `catch {}`. With a degraded
database the user lookup throws first, the re-record hits the same database and
is swallowed, and the only line emitted reads "Usage threshold notification
check failed (non-fatal)" — which is true of the outer failure and badly wrong
about the inner one. It now logs at error with the execution and workflow ids,
and says the run may be unbilled. The outer warn still covers the email path it
was written for.
**google-docs can ask Drive for a negative page.** `remaining` was
`maxDocs - previouslyFetched` unclamped, where its google-slides twin carries
`Math.max(0, …)` under the comment "Last-page precision". Both then run
`if (documents.length > remaining) documents = documents.slice(0, remaining)`,
and a negative `remaining` makes that guard true for any non-empty page while
`slice` counts from the end — keeping the leading documents and dropping the
trailing ones, where the cap says to keep none. Reachable when `maxDocs` is
lowered while a sync cursor persists. google-drive guards the same case with an
early return; google-docs had neither.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview When the billing safety net in Google Docs listing clamps Reviewed by Cursor Bugbot for commit 9c2a46a. Configure here. |
Greptile SummaryThe PR fixes two underreported failure cases.
Confidence Score: 5/5The PR appears safe to merge, with both changes narrowly correcting the described pagination and observability behavior. The connector clamp terminates capped pagination without exposing deletion reconciliation to a partial sliced listing, and the new billing diagnostic preserves structured identifiers without changing execution control flow.
|
| Filename | Overview |
|---|---|
| apps/sim/connectors/google-docs/google-docs.ts | Clamps the remaining document allowance so an exhausted cap returns no documents instead of applying negative slice semantics. |
| apps/sim/lib/logs/execution/logger.ts | Adds a throw-safe, execution-scoped error diagnostic when the fallback billing record attempt fails. |
Reviews (1): Last reviewed commit: "fix: surface an unbilled run, and clamp ..." | Re-trigger Greptile
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9c2a46a. Configure here.
| executionId, | ||
| workflowId: updatedLog.workflowId, | ||
| }) | ||
| } |
There was a problem hiding this comment.
Safety-net error log is unreachable dead code
Medium Severity
The new catch (recordError) block and its execLog.error message are unreachable for the described failure scenario. recordExecutionUsage wraps its entire body in an internal try/catch (line 1789) that swallows all errors and only logs via statsLog.error — it never throws to its caller. When the database is degraded, the safety-net call silently returns 0 and the catch (recordError) never fires. The only log emitted remains the misleading "non-fatal" warning at line 1412, so unbilled runs are not actually surfaced at error level as intended.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 9c2a46a. Configure here.


Two places where a failure is reported as something smaller than it is.
A run that is never billed logs as a notification problem
lib/logs/execution/logger.ts:1389The comment documents the safety net, not the bare
catch {}inside it.The outer
trycovers auserlookup,recordExecutionUsage, and the threshold-email calls. With a degraded database the lookup throws before the record call, the safety-net re-record hits the same degraded database and is swallowed, and the run is never billed. The only line emitted says the notification check failed and was non-fatal — true of the outer failure, badly wrong about the inner one.That is the shape that keeps a revenue-losing incident out of alerting: the log asserts the opposite of what happened.
Now logs at
errorwith the execution and workflow ids, saying the run may be unbilled. The outerwarnstill covers the email path it was written for.google-docs can ask Drive for a negative page
Both then run:
A negative
remainingmakes that guard true for any non-empty page, andslicecounts a negative end from the end — so it keeps the leading documents and drops the trailing ones, where the cap says to keep none. The wrong subset, silently, withslicedSomeset.Reachable when
maxDocsis lowered while a sync cursor persists.google-driveguards the same case a different way (an early return whenpreviouslyFetched >= maxFiles);google-docshad neither, and itsgoogle-slidestwin carries the fix under a comment marking it deliberate — it just never propagated.Scope
The logging change is observability only. The clamp changes behavior exactly in the case that is currently wrong.
Testing
1653 tests passing across
lib/logsandconnectors;bun run type-checkclean.