· Engineering Team ·
Engineering Chrome Extensions

How to Capture Console Errors in Manifest V3 Without Warnings

A technical guide to monkey-patching console.error in the Main World of a Chrome Extension.

Building a QA tool usually means building a browser extension. Since Google’s transition to Manifest V3, developers face a challenge: Content Scripts execute in an “Isolated World.”

Your extension cannot naturally intercept variables, functions, or runtime console.error logs generated by a client’s React or Vue application, which operates in the “Main World”.

The warning banner

The workaround in V2 and early V3 was attaching a debugger via chrome.debugger. The problem is that executing chrome.debugger triggers an ugly, persistent banner across the top of the browser warning the user that “An extension is debugging this browser…”. For client-facing tools, this is usually a dealbreaker.

Main World injection

To capture these React crashes silently, you can monkey-patch the console object directly within the Main World.

Instead of relying solely on the Isolated World, your content script must dynamically inject a <script> tag into the DOM that overrides console.error.

// A simplified example
const originalError = console.error;
console.error = function (...args) {
    // 1. Send argument payload to your isolated world content script
    window.postMessage({ type: 'FB_CONSOLE_ERROR', payload: args }, '*');
    
    // 2. Execute intended console.error
    originalError.apply(console, args);
};

Using window.postMessage, the Main World securely transmits the crash payload over a local bridge to your extension’s content script without triggering debugger warning banners. Uncaught errors are then safely handled by the extension.