Skip to content

fix(utils): classify browser Web Workers as browser runtime in HttpClient - #401

Merged
JosephSamirL merged 3 commits into
main-convertfrom
fix/worker-runtime-misdetected-as-server
Jun 5, 2026
Merged

fix(utils): classify browser Web Workers as browser runtime in HttpClient#401
JosephSamirL merged 3 commits into
main-convertfrom
fix/worker-runtime-misdetected-as-server

Conversation

@abbaseya

@abbaseya abbaseya commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Associated Ticket

https://app.asana.com/1/145550540855/project/1204450923340067/task/1215427653611922

What does this PR do?

Description:

  • Root cause of the Jun 3rd AWS WAF cost anomaly: determineRuntime() in packages/utils/src/http-client.ts equated "no window" with server-side, so the signals Web Worker classified as server-with-fetch and the ConvertAgent User-Agent announcement (server-side only by design) ran inside real browsers. The resulting custom request header forces a CORS preflight the signals endpoint rejects → every signals worker upload fails → the worker retry loop turns each sampled tab into ~2 preflights/second (~190M extra requests/day on the signals web ACL, worker-batched Signals collection dead since Jun 3rd).
  • Browser worker scopes are now detected via importScripts, which only exists in browser workers — Node.js and edge runtimes (Cloudflare Workers) don't expose it, so server-side and edge traffic keeps announcing ConvertAgent/1.0 for the metrics-endpoint isConvertAgentUA bot-filter bypass exactly as intended.
  • Includes an empty fix(js-sdk): commit so @convertcom/js-sdk also receives a release carrying the patched utils dependency.

Verified: HttpClient.request against a local capture server announces ConvertAgent/1.0 in a plain Node runtime and stops injecting the header when a worker scope (self.importScripts) is present. @convertcom/js-sdk-utils builds clean and its suite passes 120/120.

Related: convertcom/backend#6694 (tracking build: stop property-mangling the header name + CORS-faithful signals tests), convertcom/backend#6695 (signals endpoint: authorize the headers, stops the WAF bleed for already-deployed clients).

What type of PR is this? (check all applicable)

  • Refactor
  • Feature
  • Bug Fix
  • Hot Fix
  • Optimization
  • Documentation Update

Added tests?

  • Yes
  • No, because they aren't needed
  • No, because I need help

(determineRuntime is module-private; the integration-level regression test lives in convertcom/backend#6694 — the signals browser suite now exercises real cross-origin CORS and asserts upload delivery, which fails if this class of bug ships again.)

QA Instructions, Screenshots, Recordings

  • yarn workspace @convertcom/js-sdk-utils build && yarn workspace @convertcom/js-sdk-utils test:mocha
  • Behavioral check: import HttpClient from the built lib in Node against a local HTTP server → request carries User-Agent: ConvertAgent/1.0; set globalThis.self = {importScripts(){}} and repeat → header no longer injected
  • After the backend tracking submodule picks this up: cd public/js/tracking && yarn build:testing && yarn test:signals --reporter=list stays 9/9

abbaseya and others added 2 commits June 5, 2026 18:56
…ient

determineRuntime() equated 'no window' with server-side, so the signals Web
Worker fell into 'server-with-fetch' and the ConvertAgent User-Agent
announcement (meant for server-side SDK traffic only) ran inside real
browsers. The resulting custom header forced a CORS preflight the signals
endpoint rejects, breaking every signals worker upload and driving the WAF
retry storm. Browser worker scopes are now detected via importScripts, which
server runtimes (Node.js) and edge runtimes (Cloudflare Workers) do not
expose, so those keep announcing ConvertAgent as intended.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Empty release commit so @convertcom/js-sdk ships a new version carrying the
patched @convertcom/js-sdk-utils dependency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@abbaseya abbaseya self-assigned this Jun 5, 2026
@abbaseya
abbaseya requested a review from a team June 5, 2026 15:57

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request updates the runtime detection logic in packages/utils/src/http-client.ts to correctly identify browser Web Workers by checking for the presence of self and self.importScripts, preventing them from being misclassified as server runtimes. The feedback suggests using optional chaining when accessing importScripts on self to prevent potential TypeErrors if self is null in mocked or custom environments.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/utils/src/http-client.ts
typeof null is 'object', so a mocked environment defining self = null passed
the typeof guard and the importScripts access would throw. Optional chaining
degrades it to undefined and falls through to the server checks, matching the
file's existing navigator?.sendBeacon idiom.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Jun 5, 2026

Copy link
Copy Markdown

@JosephSamirL
JosephSamirL merged commit e17f06e into main-convert Jun 5, 2026
5 checks passed
@JosephSamirL
JosephSamirL deleted the fix/worker-runtime-misdetected-as-server branch June 5, 2026 16:21
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.

2 participants