quasarframework/quasar · warning

Failed to query the tabs to revive the content script connec

Error message

Failed to query the tabs to revive the content script connections.

What it means

The BEX bridge's internal #revivePortClients routine asks the browser tabs API (chrome.tabs.query({})) to enumerate open tabs so it can re-establish content-script connections (e.g. after a background worker restarts in MV3). When the tabs.query call rejects, the bridge logs this warning and returns, leaving content-script connections unreopened.

Source

Thrown at app-vite/exports/bex/private/bex-bridge.js:499

   * Should be used only by the background script.
   *
   * The clients cannot be reached through ports (none are available on a
   * fresh background script start), so one-off runtime messages are used.
   */
  async #revivePortClients() {
    // reach the app (popup / devtools / options / extension pages)
    runtime.sendMessage(reviveSignature).catch(() => {
      // no app page is listening
    })

    if (tabs === void 0) return

    let tabList

    try {
      tabList = await tabs.query({})
    } catch (err) {
      this.warn(
        'Failed to query the tabs to revive the content script connections.',
        err
      )
      return
    }

    // reach the content scripts
    for (const { id } of tabList) {
      if (id !== void 0) {
        tabs.sendMessage(id, reviveSignature).catch(() => {
          // no content script is listening on this tab
        })
      }
    }
  }

  /**
   * The requested port might be just about to (re)register itself (e.g.

View on GitHub (pinned to 4841521b5f)

Solutions

  1. Add the 'tabs' permission to the manifest section of your BEX manifest file
  2. Check the companion `err` object logged with the warning for the underlying browser API error
  3. Ensure the bridge is only instantiated in extension contexts where chrome.tabs exists (background/content scripts)
  4. Restart the dev server / reload the extension if it was a transient service-worker restart race

Example fix

// before (src-bex/manifest.json)
{
  "permissions": []
}
// after
{
  "permissions": ["tabs"]
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before instantiating the bridge in an extension context
if (typeof chrome !== 'undefined' && chrome.tabs && chrome.tabs.query) {
  // tabs API available; also ensure manifest declares "permissions": ["tabs"]
}

Type guard

function hasTabsApi(api) {
  return typeof api !== 'undefined' && typeof api.query === 'function'
}
// usage: hasTabsApi(globalThis.chrome?.tabs)

Try / catch

try {
  await bridge.send('my.event', payload)
} catch (err) {
  if (String(err).includes('tabs')) {
    console.warn('Tabs API unavailable: check "tabs" permission in BEX manifest')
  }
}

Prevention

When it happens

Trigger: Constructor-time revival runs and chrome.tabs.query rejects — typically due to missing 'tabs' permission in manifest.json, an unsupported context (no tabs API, e.g. some extension surfaces), or a transient browser API failure during service-worker shutdown/restart.

Common situations: MV3 service worker restart reviving ports; developer forgot the 'tabs' permission in the BEX manifest's bex section; running the bridge in a context where chrome.tabs is undefined (options page of certain builds, or non-Chromium targets); testing in a browser whose extension APIs are partially unavailable.

Related errors


AI-assisted analysis of quasarframework/quasar@4841521b5f (2026-08-30). Data as JSON: /api/errors/5604c2e95d5cf53f. Report an issue: GitHub.