Skip to content

Hotfix: bind fetch to globalThis to avoid 'Illegal invocation' - #9

Merged
unforced merged 1 commit into
mainfrom
hotfix/fetch-binding
Apr 18, 2026
Merged

Hotfix: bind fetch to globalThis to avoid 'Illegal invocation'#9
unforced merged 1 commit into
mainfrom
hotfix/fetch-binding

Conversation

@unforced

Copy link
Copy Markdown
Contributor

Summary

  • Browser's native fetch requires this === Window. Storing a bare fetch reference on VaultClient.fetchImpl (or as a default param in oauth/discovery helpers) loses that binding — at call-time this is the VaultClient instance and the browser throws TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation.
  • jsdom's fetch is permissive and didn't enforce the invariant, so existing tests passed while the browser broke.
  • Fix: fetch.bind(globalThis) in all four default paths — VaultClient constructor, discoverAuthServer, registerClient, beginOAuth, completeOAuth.
  • Regression test installs a this-aware fetch shim that throws "Illegal invocation" when this !== globalThis, instantiates VaultClient without an explicit fetchImpl, and asserts vaultInfo() resolves. Verified it fails without the fix.

Test plan

  • bun run lint clean
  • bun run typecheck clean
  • bun run test — 101 tests pass (new regression included)
  • bun run build succeeds
  • Reverted fix + re-ran regression test → failed with the exact browser error, confirming coverage
  • Aaron verifies in browser that vault sign-in completes without "Illegal invocation"

🤖 Generated with Claude Code

Storing the native browser fetch as a bare reference on an instance
field (VaultClient.fetchImpl) or as a default parameter loses its
Window receiver. At call time the browser sees `this !== Window` and
throws TypeError: Failed to execute 'fetch' on 'Window': Illegal
invocation. jsdom's fetch is permissive and didn't catch this.

Bind `fetch` to `globalThis` in all four default paths (VaultClient
constructor, discoverAuthServer, registerClient, beginOAuth,
completeOAuth). Add a regression test that installs a this-aware
fetch shim mimicking the browser's check — instantiates VaultClient
without an explicit fetchImpl and confirms vaultInfo() resolves.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@unforced
unforced merged commit ea41003 into main Apr 18, 2026
@unforced
unforced deleted the hotfix/fetch-binding branch April 18, 2026 22:23
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