Skip to content

fix(platform): resolve autopilot beta blockers (SECRT-2266/2267/2268/2269) - #12874

Merged
ntindle merged 54 commits into
devfrom
ntindle/diagnose-autopilot-beta-blockers
Apr 23, 2026
Merged

fix(platform): resolve autopilot beta blockers (SECRT-2266/2267/2268/2269)#12874
ntindle merged 54 commits into
devfrom
ntindle/diagnose-autopilot-beta-blockers

Conversation

@ntindle

@ntindle ntindle commented Apr 21, 2026

Copy link
Copy Markdown
Member

Why / What / How

Why: A beta user spent significant time trying to build and run agents that read Google Sheets. Four separate failures compounded on their session — all already open in Linear as SECRT-2266 through SECRT-2269. Three in-flight PRs each addressed a piece but conflicted on the same files (backend/data/model.py, backend/blocks/_base.py, autogpt_libs/.../types.py), so landing them individually would have been churn. One of the four reported issues (the credential-delete crash) is also the top unresolved Sentry issue AUTOGPT-SERVER-6HB with 100+ events going back to 2025-10-20 — it was archived as "ignored" but is a real regression. Bug #4 required new work; the others we got by adopting the existing open PRs and addressing a pending review comment.

What: This PR consolidates the three in-flight PRs, adds the two pieces of new work needed to fully close the beta blockers, and addresses the pending review on one of the three PRs so it doesn't require a second round.

How:

  1. Adopt PR fix(platform): Fix Google Drive auto-credentials handling across the platform #12004 (Bug 1 — auto-credentials resolution). Tags Drive-file fields as is_auto_credential on CredentialsFieldInfo, exposes BlockSchema.get_auto_credentials_fields() and Graph.regular_credentials_inputs / auto_credentials_inputs, extracts _acquire_auto_credentials() in the executor to resolve embedded _credentials_id at run time, clears _credentials_id on agent fork so cloned agents don't inherit the original author's credential, and fixes the Firefox referrer policy on the Google Drive picker script load.

  2. Adopt PR feat(platform): add incremental OAuth authorization for scope upgrades #12748 (Bug 3 — credential accumulation). OAuth callback now merges scopes into an existing credential (explicit via credential_id in OAuth state, or implicit via provider + username match) instead of appending a new row on every reconnect. GitHub's non-incremental OAuth path requests the union of existing + new scopes at login so the upgrade path works there too.

  3. Replace PR fix(blocks): prevent TypeError when auto_credentials field is empty #12588 with a systemic None-guard (addresses reviewer feedback). The original PR added a per-block credentials: GoogleCredentials | None = None + early guard pattern that would need to be repeated across 50+ blocks with GoogleDriveFileField. Per the reviewer's ask, we moved the guard into Block._execute() once: after the setdefault loop, if kwargs[kwarg_name] is None we raise BlockExecutionError with a clean user-facing message. The per-block change in sheets.py is dropped so credentials: GoogleCredentials stays non-Optional. Dry-run path skips the guard (executor intentionally runs blocks without resolved creds for schema validation).

  4. Fix Bug 2 — Google revoke_tokens (SECRT-2267, AUTOGPT-SERVER-6HB). revoke_tokens() was handing our Pydantic OAuth2Credentials into google-auth's AuthorizedSession, which calls self.credentials.before_request(...) on the object and crashes with AttributeError: 'OAuth2Credentials' object has no attribute 'before_request'. Google's token revoke endpoint doesn't need any auth header — just token=<token> in the form body per Google's docs. Switched to the platform's async Requests helper, matching how reddit.py / github.py / todoist.py / other providers do revocation. No google-auth objects involved.

  5. Fix Bug 4 — hardcoded Drive file IDs in agent graphs (SECRT-2269). Evidence from the beta user's session: CoPilot's agent-builder produced 13 saved graph versions in one session where each one stuffed either a bare string ("1KAv…") or a partial object ({"id": "1KAv…"}) into GoogleSheetsReadBlock.constantInput.spreadsheet, never wiring an AgentGoogleDriveFileInputBlock as the intended input. Bare-string versions failed pydantic validation with is not of type 'object'; object-with-only-id versions would have crashed at run time because _acquire_auto_credentials has no _credentials_id to resolve. Added a validator in GraphModel._validate_graph_get_errors that flags any auto-credentials field whose input_default.<field> is a bare string OR a dict missing _credentials_id, when there's no upstream link feeding the field. Remediation text is format-aware: when field_schema["format"] == "google-drive-picker" it names AgentGoogleDriveFileInputBlock specifically; for any other future auto-credentials format (OneDrive / Dropbox / etc.) the remediation is generic, so we don't ship a stale Google-specific hint that doesn't apply.

A companion handoff for the CoPilot agent-builder team is drafted at /tmp/agent-builder-ticket-drive-file-input.md (to be filed in their tracker). The validator here is a safety net so reviewers and the LLM both get a clear error with the correct remediation; the agent-builder itself still needs to learn the correct pattern so it stops trying to hardcode Drive files in the first place.

Changes 🏗️

Backend

Frontend

Shared libs

Test plan 📋

  • poetry run lint — clean
  • poetry run pytest backend/data/graph_test.py — 55 passed including 11 new validator tests
  • poetry run pytest backend/integrations/oauth/google_test.py — 3 new tests passing
  • poetry run pytest backend/blocks/google/sheets_test.py — 2 new tests passing
  • poetry run pytest backend/blocks/google/ backend/integrations/oauth/ backend/executor/ backend/data/graph_test.py backend/api/features/integrations/ backend/copilot/tools/utils_test.py — 250 passed, 6 pre-existing failures that require the docker stack (RabbitMQ/Redis/Postgres) and fail identically on origin/dev
  • pnpm format — clean
  • pnpm lint — 3 pre-existing <img> warnings on files I didn't touch, no errors
  • pnpm types — pre-existing errors on AgentActivityDropdown that also fail on origin/dev (unrelated to this PR; needs a separate fix on dev)
  • Live repro on dev verified Bug 2 fires against current prod code — two fresh Sentry events in AUTOGPT-SERVER-6HB at 2026-04-21T21:35:54Z on app:dev-behave:cloud matching the exact DELETE /api/integrations/google/credentials/{cred_id} path. Airtable OAuth2 delete as a control worked cleanly, confirming Google-specific.
  • Live repro on dev verified Bug 4 (CoPilot direct-run variant) — {"spreadsheet": {"id": "..."}}Cannot use file 'None' (type: None) from _validate_spreadsheet_file mimeType check, as expected.

Reviewer post-merge verification:

  • Delete a Google OAuth credential via the Integrations UI — succeeds cleanly, no Sentry event fires
  • Connect Google twice (same account, same scopes) — credential count stays at 1 (dedup)
  • Save an agent graph with GoogleSheetsReadBlock.constantInput.spreadsheet = "bare-id" via API — graph validator rejects with AgentGoogleDriveFileInputBlock remediation
  • Save an agent graph with GoogleSheetsReadBlock whose spreadsheet is fed by an upstream AgentGoogleDriveFileInputBlock.result — validator accepts, agent runs

Out of scope (for follow-ups)

  • Bug 1 — "Failed to retrieve Google OAuth credentials" in frontend/src/components/contextual/GoogleDrivePicker/useGoogleDrivePicker.ts:163. Zero hits for this string in the beta user's Langfuse traces and we weren't able to reproduce it from a clean flow. Most likely a stale-credential race condition (delete in another tab, picker queries a stale React-Query cache). Tracked as a separate task; not blocking.
  • CoPilot first-attempt mimeType retry loop. Observed on dev: CoPilot's first call to GoogleSheetsReadBlock sends {"spreadsheet": {"id": "..."}} without mimeType, hits _validate_spreadsheet_file, retries with mimeType. Costs a round-trip. Two possible fixes (relax _validate_spreadsheet_file to skip when mimeType is None and let Google's API surface the real error; OR extend get_auto_credentials_fields metadata so CoPilot's tool description prompts it to always include mimeType). Deliberately deferred — fixing only one of "API caller sends a bare string" or "CoPilot sends an incomplete object" risked the same auth-ambiguity the bare-string commit in this branch history hit.
  • CoPilot agent-builder prompt/guide update. The validator here produces the correct error message, but the agent-builder model still needs to learn to use AgentGoogleDriveFileInputBlock upfront rather than discover it through validator retries. Separate handoff ticket filed.

🤖 Generated with Claude Code


Note

Medium Risk
Touches OAuth credential issuance/upgrade paths and introduces a new endpoint that returns raw access tokens (scope-gated), plus broad changes to execution-time credential resolution/validation; mistakes could impact auth/security or break integrations.

Overview
Fixes several Google/Drive agent-builder blockers by supporting incremental OAuth scope upgrades and by hardening how credential-bearing file inputs (“auto-credentials”) are validated, resolved, and cleared on graph fork.

On the integrations API, /{provider}/login now accepts credential_id and persists it in OAuthState to upgrade an existing OAuth2 credential on callback (explicit upgrade), with an implicit merge path for same provider+username. The callback path now merges scopes/metadata, preserves ID/title, preserves existing refresh_token/username when missing from incremental responses, blocks upgrades for managed/system credentials, and adds a new /{provider}/credentials/{cred_id}/picker-token endpoint to return a short-lived access token for provider-hosted pickers (currently allowlisted to Google Drive scopes).

For auto-credentials, CredentialsFieldInfo gains is_auto_credential + input_field_name, graphs now expose regular_credentials_inputs vs auto_credentials_inputs, and multiple callers switch from aggregate_credentials_inputs() to regular_credentials_inputs so embedded picker credentials aren’t treated as user-mapped inputs. Execution-time auto-credential acquisition is extracted into _acquire_auto_credentials() with clearer error handling and lock cleanup; block execution adds a systemic guard to surface a clean Missing credentials error when auto-credentials are absent.

Separately fixes Google credential deletion by rewriting GoogleOAuthHandler.revoke_tokens() to use the platform Requests helper (bounded retries) instead of AuthorizedSession, and expands test coverage across these flows (incremental OAuth, picker-token, auto-credential validation/acquisition, graph validator, and frontend diagnostics test stubs).

Reviewed by Cursor Bugbot for commit cac36ea. Bugbot is set up for automated code reviews on this repo. Configure here.

ntindle and others added 23 commits February 6, 2026 16:08
…platform

- Tag auto-credentials with `is_auto_credential` and `input_field_name` on `CredentialsFieldInfo` to distinguish them from regular user-provided credentials
- Add `regular_credentials_inputs` and `auto_credentials_inputs` properties to `Graph` so UI schemas, CoPilot, and library presets only surface regular credentials
- Extract `_acquire_auto_credentials()` helper in executor to resolve embedded `_credentials_id` at execution time with proper lock management
- Validate auto-credentials ownership in `_validate_node_input_credentials()` to catch stale/missing credentials before execution
- Clear `_credentials_id` in `_reassign_ids()` on graph fork so cloned agents require re-authentication
- Propagate `is_auto_credential` through `combine()` and `discriminate()` on `CredentialsFieldInfo`
- Add `referrerPolicy: "no-referrer-when-downgrade"` to Google API script loading to fix Firefox API key validation
- Comprehensive test coverage for all new behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adapt auto-credentials filtering to dev's refactored graph model:
- aggregate_credentials_inputs() now returns 3-tuples (field_info, node_pairs, is_required)
- credentials_input_schema moved to GraphModel, builds JSON schema directly
- Update regular/auto_credentials_inputs properties for 3-tuple format
- Update test mocks and assertions for new tuple format and class hierarchy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap get_creds_by_id call in try/except in the auto-credentials
validation path to match the error handling pattern used for regular
credentials.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…o None

Setting _credentials_id to None on fork was ambiguous — both "forked,
needs re-auth" and "chained data from upstream" were represented as None.
This caused _acquire_auto_credentials to silently skip credential
acquisition for forked agents, leading to confusing TypeErrors at runtime.

Now the key is deleted entirely, making the three states unambiguous:
- Present with value: user-selected credentials
- Present as None: chained data from upstream block
- Absent: forked/needs re-authentication

Also adds pre-run validation for the missing key case and makes error
messages provider-agnostic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the _reassign_ids section comment to above the actual _reassign_ids
tests, and label the combine() tests correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…schema

Post-refactor fix: these fields were moved from data/block.py to blocks/_base.py in #12068
Resolved conflicts:
- executor/utils.py: kept auto-credentials validation + dev's comment update
- graph_test.py: kept both auto-credentials tests AND MCP deduplication tests
Allow users to upgrade existing OAuth credentials with additional scopes
instead of creating duplicate credentials. Google uses native incremental
auth (include_granted_scopes), GitHub uses scope union in login URL.

Backend: OAuthState gains credential_id field, login endpoint accepts
credential_id param, callback merges scopes into existing credentials or
auto-detects same provider+username for implicit merge.

Frontend: API client passes credential_id, credentials provider upserts
on callback, useCredentials splits into saved vs upgradeable lists,
useCredentialsInput exposes handleScopeUpgrade.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use provider_matches() for Python 3.13 StrEnum compat (sentry, coderabbitai)
- Filter out managed/system credentials from implicit merge (cursor)
- Skip implicit merge when credentials.username is None (sentry)
- Preserve existing metadata on credential upgrade (cursor)
- Fix test factories to use `is not None` instead of `or` (coderabbitai)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e metadata

- Reject managed/system credentials in both _prepare_scope_upgrade and
  _upgrade_existing_credential with 400 (coderabbitai, sentry)
- Guard metadata merge against None values (coderabbitai)
- Fix test helper _make_state_with_credential_id scopes pattern (cursor)
- Add 4 new tests confirming each fix

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pulls origin/ntindle/google-issues-fix into the combined beta-blocker
branch. Covers SECRT-2266 (Google Drive OAuth retrieval failure): tags
auto-credentials in the data model, resolves embedded _credentials_id
at execution time, clears _credentials_id on agent fork, hardens the
Firefox referrer on the Google Drive picker, and filters auto-creds
out of the CoPilot "missing credentials" and library preset prompts.

Conflicts resolved:
- backend/data/model.py: kept HEAD's defensive set() copy AND added
  #12004's is_auto_credential + input_field_name on CredentialsFieldInfo
- backend/executor/utils_test.py: kept both test groups (HEAD's
  credential error marker parity + #12004's auto-credentials
  validation)
- backend/copilot/tools/utils_test.py: file was added by #12004 at the
  old path backend/api/features/chat/tools/utils_test.py; git rename
  detection moved it to the new copilot/ location. Updated the in-file
  import strings from backend.api.features.chat.tools.utils to
  backend.copilot.tools.utils to match the post-rename module.

66 tests pass in copilot/tools/utils_test.py, executor/utils_test.py,
data/graph_test.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces PR #12588 with majdyz's recommended approach. Instead of a
per-block ``credentials: GoogleCredentials | None = None`` guard (which
would have to be repeated across 50+ blocks using ``GoogleDriveFileField``),
injects the check into ``Block._execute()`` once:

  for kwarg_name in self.input_schema.get_auto_credentials_fields():
      kwargs.setdefault(kwarg_name, None)
      if kwargs[kwarg_name] is None:
          raise BlockExecutionError("Missing credentials for '{name}'. ...")

Benefits over per-block guards:
- No ``credentials: GoogleCredentials`` → ``GoogleCredentials | None``
  churn on individual blocks; type contracts stay non-Optional.
- New auto-credential blocks inherit the guard automatically.
- Dry-run path skips the guard (executor runs blocks without resolved
  credentials for schema validation).

Tests in backend/blocks/google/sheets_test.py pin the contract:
- Valid spreadsheet, no credentials → clean BlockExecutionError
- No spreadsheet, no credentials → same clean error (credentials guard
  fires before the block's own ``No spreadsheet selected`` path)

Addresses the credentials-missing half of SECRT-2269.
Supersedes #12588.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…auth AuthorizedSession

Revoking a Google credential crashed with:
  AttributeError: 'OAuth2Credentials' object has no attribute 'before_request'
  at backend/integrations/oauth/google.py:111 in revoke_tokens

revoke_tokens() used google-auth's AuthorizedSession with our Pydantic
OAuth2Credentials model. AuthorizedSession.request() unconditionally
calls self.credentials.before_request(...), which only exists on
google-auth's Credentials class.

Google's revoke endpoint doesn't need any authentication, just the
token in the form body (see https://developers.google.com/identity/
protocols/oauth2/web-server#tokenrevoke). Switched to backend's async
Requests helper, matching how the other OAuth providers (reddit,
github, etc.) already do revocation. No google-auth objects involved.

Regression tests in integrations/oauth/google_test.py cover:
- Happy path: POST to revoke endpoint with token in form body
- Returns False when access_token is missing (don't crash)
- Returns False on non-2xx response

Fixes SECRT-2267, AUTOGPT-SERVER-6HB (100 events, status=ignored).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
API callers sending just a spreadsheet ID (e.g. pasted from a Drive
URL) hit a pydantic ValidationError because the block schema expected
a full GoogleDriveFile object. The UI picker always sent the object,
so the UI worked but the API did not — API/UI mismatch.

Added a model_validator(mode="before") that promotes a bare string
input to {id: <str>}. The picker's full-object path continues to work
unchanged (still carries ``_credentials_id``). Non-string / non-dict
values still raise ValidationError so we don't silently swallow real
bad input.

Fixes SECRT-2269 (API side).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…validator

Evidence from a beta user's Langfuse session 92363101 + the resulting
Supabase rows: across 13 saved versions of one agent, CoPilot's
agent-builder kept stuffing a bare Drive file ID into
GoogleSheetsReadBlock.constantInput.spreadsheet (v4-v10) and later a
partial `{"id": "…"}` object (v11-v13), never wiring an
AgentGoogleDriveFileInputBlock despite finding it via `find_block`
earlier in the session. v4-v10 failed pydantic validation with
"'1KAv…' is not of type 'object'" — which the user pasted back into
chat — and v11-v13 passed pydantic but would have crashed at run time
because `_acquire_auto_credentials` in manager.py has no
`_credentials_id` to resolve.

Adds a defence-in-depth validator in `_validate_graph_get_errors`
that flags any auto-credentials field whose `input_default.<field>`
is a bare string OR a dict missing `_credentials_id`, when there's no
upstream link feeding the field.

Remediation text is format-aware: when `field_schema["format"] ==
"google-drive-picker"` the error points at AgentGoogleDriveFileInputBlock
specifically. For any other auto-credentials format (future OneDrive
/ Dropbox pickers etc.) the remediation is generic ("wire the matching
input block for this provider") so we don't ship stale Google-specific
hints when the actual provider differs.

Companion handoff for the CoPilot agent-builder team is drafted at
/tmp/agent-builder-ticket-drive-file-input.md — the validator is a
safety net, not a substitute for teaching the model the right pattern.

Tests (11 new, all passing):
- bare string real ID (v7-v10 shape) -> rejected with Drive-picker text
- placeholder string (v4-v6 shape) -> rejected
- partial object missing _credentials_id (v11-v13 shape) -> rejected
- empty-string _credentials_id -> rejected (executor treats as missing)
- fully hydrated object with _credentials_id -> accepted
- upstream link from AgentGoogleDriveFileInputBlock -> accepted
- unset field with no link -> no double error with required-field check
- bare string on a non-auto-credentials field -> not flagged
- multi-block anti-pattern -> each bad node flagged independently
- non-google-picker format -> caught but with generic remediation
- regular credentials field (Gmail) -> not flagged

Also absorbs an isort-driven one-line reflow in copilot/tools/
utils_test.py from running poetry run format after the #12004 merge
(Boy Scout).

Addresses SECRT-2269 (platform side).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
poetry run format auto-simplified three assert-with-trailing-tuple
expressions in the new auto-credentials validator tests into single-
line asserts. No behavioural change; tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ntindle
ntindle requested a review from a team as a code owner April 21, 2026 21:58
@ntindle
ntindle requested review from Pwuts and Swiftyos and removed request for a team April 21, 2026 21:58
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Apr 21, 2026
@github-actions github-actions Bot added the platform/frontend AutoGPT Platform - Front end label Apr 21, 2026
Comment thread autogpt_platform/backend/backend/executor/utils.py Outdated
Comment thread autogpt_platform/backend/backend/executor/manager.py
…cred error

Two cursor review items on commit ad7021f:

- Cursor Low (thread PRRT_kwDOJKSTjM58sEDe): the `_mark_optional_skip`
  closure was being redefined on every iteration of the inner
  auto-credential field loop. Move it to the outer per-node scope so
  it's defined once per node. Still captures node.id correctly, no
  behavior change.

- Cursor Medium (thread PRRT_kwDOJKSTjM58sEDl): the `else` branch in
  `_acquire_auto_credentials` used to raise "No file selected" for ANY
  truthy non-dict `field_data` (e.g. a bare Drive ID string that
  bypassed the graph validator — API callers, legacy graphs). The
  message was misleading because the value *was* provided, it just had
  the wrong shape. Split into two branches: None/empty → "No file
  selected" (unchanged); non-dict truthy → a new error that names both
  the field and the actual type, pointing at the picker as the fix.

Parametrized regression test covers bare-string, int, bool, and list
inputs — pins the type-name requirement so a future cleanup can't
silently regress the message.
Comment thread autogpt_platform/backend/backend/blocks/_base.py Outdated
Sentry HIGH (thread PRRT_kwDOJKSTjM58sJfA): the None-guard in
``Block._execute()`` used ``field_value.get("_credentials_id")`` and
treated the result's truthiness as "creds available". The documented
chained-upstream pattern ships the picker object with
``_credentials_id=None`` — the executor fills in the resolved id
between prep and run(). But ``None`` is falsy, so the guard raised
``BlockExecutionError("Missing credentials")`` on every valid chained
graph (e.g. AgentGoogleDriveFileInputBlock → GoogleSheetsReadBlock).

Switch to ``"_credentials_id" in field_value`` — the key's presence is
the chained-skip signal (mirrors the rule ``_acquire_auto_credentials``
uses at manager.py:166: ``if cred_id is None: continue``). A dict that
truly lacks the key (hardcoded without creds) still trips the guard.

Pin with a regression test that reproduces Mehmet's v13 graph shape:
spreadsheet dict with ``_credentials_id: None`` must reach run() (we
patch the provider SDK build to detect that boundary) — not be
preempted with "Missing credentials".
@github-actions github-actions Bot removed the documentation Improvements or additions to documentation label Apr 22, 2026
ntindle and others added 2 commits April 22, 2026 13:25
Without an `__init__.py`, pytest's default `prepend` import mode adds
`backend/blocks/google/` to `sys.path[0]` when it collects a test file
under that directory (the new `sheets_test.py` is the trigger). That
makes `backend/blocks/google/calendar.py` importable as bare
`calendar`, shadowing the stdlib. A `multiprocessing.forkserver`
subprocess inherits the polluted `sys.path`; when the forkserver child
re-imports pytest via `_fixup_main_from_path`, `email._parseaddr`
does `import calendar` and resolves our file instead of the stdlib,
which re-enters `email.utils` and crashes with a circular-import
`ImportError` on `_has_surrogates`. Every `AppProcess` subprocess
(DatabaseManager, ExecutionManager, AgentServer, ...) dies silently;
subsequent IPC calls (e.g. `OrchestratorBlock._create_tool_node_signatures`)
hang through the full `conn_retry` loop (100 * 30s) and burn the
15-minute CI budget.

Adding the empty `__init__.py` promotes `google/` to a regular package;
pytest walks up to `autogpt_platform/backend/` for the `sys.path` entry
instead, so `calendar.py` is no longer reachable as `calendar` and the
subprocess re-imports stdlib cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Apr 22, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ff67797. Configure here.

Comment thread autogpt_platform/backend/backend/executor/manager.py
ntindle and others added 6 commits April 22, 2026 13:48
…or tests

The Google Sheets / Gmail blocks auto-disable when `GOOGLE_CLIENT_ID` /
`GOOGLE_CLIENT_SECRET` are unset, which is the case in CI. The graph
validator short-circuits disabled blocks at `graph.py:798` before
reaching the auto-credentials anti-pattern branch these tests exercise,
so all 14 `test_auto_credentials_*` assertions failed with "Block is
disabled and cannot be used in graphs" instead of the expected
auto-creds error messages.

Add a name-gated autouse fixture that flips `GOOGLE_SHEETS_DISABLED`
and `GOOGLE_OAUTH_IS_CONFIGURED` for the auto-creds test group only;
other tests in this file retain the real env-derived values.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…oundary

Adds five new test files + expands the admin diagnostics page test to
cover the rendered-dashboard and error branches. Targets the lowest
patch-coverage files in the PR so platform-frontend-ci hits its 80%
threshold:

- SubscriptionTierSection/helpers.test.ts — formatCost / getTierLabel /
  formatPendingDate (pure unit tests)
- PendingChangeBanner.test.tsx — cancel vs downgrade copy, button
  disabled while busy, null-date bail-out
- PanelHeader.test.tsx — revert-button visibility and aria-label,
  click callbacks
- ArtifactErrorBoundary.test.tsx — children render, fallback with
  error text, structured clipboard payload on Copy
- useDiagnosticsContent.test.ts — loading / error coalescing and
  refresh fanout across the three composed queries
- diagnostics/__tests__/page.test.tsx — extended to cover error state,
  zeroed happy path, and critical-issues alert-card rendering

Also fixes a pre-existing timezone flake in
SubscriptionTierSection.test.tsx — the `2026-05-15T00:00:00Z` literal
drifts to May 14 in any timezone west of UTC, so the test passes in
CI (UTC) but fails locally. Moved to noon UTC to match the pattern
used in the other new tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add renderHook tests for React hook wrappers that delegate to
already-tested pure functions, pushing codecov/patch/platform-frontend
above the 80% threshold:

- client.test.ts: BackendAPI.oAuthLogin delegates to _get + buildOAuthLoginQuery
- useCredentials.test.ts: upgradeableCredentials exposed via context provider
- useCredentialsInput.test.ts: scope upgrade flow, OAuth login delegation
- useGoogleDrivePicker.test.ts: openPicker credential flow (insufficient
  scopes, happy path with picker token, non-oauth2 credential error)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove unused React and vi imports
- Add non-null assertions for discriminated union properties in tests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 👍🏼 Mergeable in AutoGPT development kanban Apr 23, 2026
@ntindle
ntindle added this pull request to the merge queue Apr 23, 2026
Merged via the queue into dev with commit 10e421c Apr 23, 2026
46 checks passed
@ntindle
ntindle deleted the ntindle/diagnose-autopilot-beta-blockers branch April 23, 2026 17:33
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban Apr 23, 2026
@github-project-automation github-project-automation Bot moved this to Done in Frontend Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation platform/backend AutoGPT Platform - Back end platform/blocks platform/frontend AutoGPT Platform - Front end size/xl

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants