Skip to content

dispose() rejects with "row <id> is disabled" and skips the rest of teardown #38

Closed

Description

@iceteaSA

What happens

With OAuth account rows disabled (enabled: false) in the account store, every OpenCode exit logs:

level=ERROR message="plugin dispose hook failed" error="row <id> is disabled"

Observed on every exit (5 times in one day) with @cortexkit/opencode-antigravity-auth 3.0.4, matching upstream main at 48919aa. Both configured OAuth rows were disabled.

Where it comes from

  • PluginResult.dispose calls lifecycle.dispose() (packages/opencode/src/plugin/index.ts:956-959), which first awaits disposeAccountRuntime() (packages/opencode/src/plugin/lifecycle.ts:225).
  • disposeAccountRuntime() (lifecycle.ts:133-163) has two awaits that can reject:
    • await liveQueueDrained at :157. The void liveQueueDrained.catch(() => {}) at :152 silences the unhandled-rejection warning, but the later await still throws.
    • if (failed) throw failed.reason at :163 rethrows the first retired runtime that rejected.
  • The store's enabled-row guard throws row-disabled (packages/core/src/common-auth-embedded/store/refresh.js:20-21). CoreAccountManager.refreshAccount() (packages/core/src/account-manager.ts:1248-1257) calls repository.refresh() without checking enabled. The proactive refresh queue skips disabled accounts (packages/opencode/src/plugin/refresh-queue.ts:179-183), but only when it selects accounts on a tick.

I haven't pinned down which in-flight operation is refreshing the disabled row at exit.

Impact

This skips more than logging. If disposeAccountRuntime() throws, the rest of dispose() (lifecycle.ts:226-246) doesn't run: disk signature cache shutdown, producer disposal, the sidebar write drain, and consumer disposal (RPC server, file logger) are skipped.

Repro

  1. Disable the OAuth account rows in the account store (enabled: false).
  2. Start OpenCode, run a session, then exit.
  3. The log shows the ERROR line above.

Expected

A disabled row during teardown has nothing to refresh. dispose() should complete and run every teardown step. Either of these fixes would work:

  • Check enabled in refreshAccount() (or before scheduling a refresh) so a disabled row is never refreshed.
  • Settle the drains in disposeAccountRuntime() (Promise.allSettled, log the failures) so one failed refresh can't abort teardown.

For comparison, openai-auth skips disabled accounts before its quota refresh (packages/core/src/refresh-all-quota.ts:323-332 in cortexkit/openai-auth).

Activity

  1. agauth-alfonso commented on Oct 23, 2026

    @agauth-alfonso

    Thanks for tracing this. We confirmed that if one cleanup step fails during shutdown, the plugin stops there and skips the steps after it. That's still the case in 3.0.10. We're changing shutdown so it runs every remaining step even after a failure, keeps the error visible, and still drains requests and writes in the right order.

    We haven't yet found which operation produces your row … is disabled error. Disabled accounts are already skipped when proactive refreshes are picked, so we don't want to guess at the cause. If it still happens after the fix, a stack trace for that error would help us find it. Please remove tokens and account details first. We can fix the shutdown problem without it.

  2. agauth-alfonso commented on Oct 23, 2026

    @agauth-alfonso

    Fixed in 3.0.11. If one cleanup step fails during shutdown, the plugin now still runs every remaining step, in the same order, and reports the error after cleanup. Please upgrade. If the row … is disabled error still appears, please open a new issue with its stack trace, removing tokens and account details first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions