Signals and Diagnostics
Extension state is hard-isolated by design — see the overview — which means extensions need a sanctioned way to talk to each other and to an operator. Signals are that channel.
What a signal is
ctx.helpers.emitSignal({
signalType: 'page.captcha-suspected', // built-in types are open: (string & {}) too
severity: 'warn', // 'info' | 'warn' | 'error'
annotations: { url: page.url() },
});
Where it goes
- Other extensions, in-run. Fans out synchronously to every
onSignalhandler, depth-capped at 3 so a signal storm can't wedge a run. - The Extensions admin dashboard. Batched and persisted (default: every second or every 100 signals, whichever comes first) with automatic redaction of any field whose key looks like a secret (
password,token,cookie,authorization,credential,proxy, and similar). Visible per-extension and per-run in the Manage Extensions detail view. - The activity log, but only for
severity: 'error'— this is the operator-visible escalation path, opt-in by severity rather than by every emission. - The framework's own audit trail.
route.decided,route.response-modified,run.outcome-overridden,challenger.handler-error, andchallenger.config-invalidare emitted automatically, so a run's signal history reads as a story even if every extension involved only ever observes.
A run that comes back BLOCKED with no signals is a mystery. A run with network.challenge-header → page.captcha-suspected → proxy.endpoint-failed tells you what happened, in order, without reading a log file.
Diagnostics: the layer below signals
Signals are a domain concept — they mean something to an extension author. Underneath them, packages/browser also reports lower-level plumbing failures (a route.fetch that failed because a proxy died, a handler dispatch that threw) through an optional session.diagnostic(scope, message, error) call, implemented by the host against its structured logger and correlated by task id. This exists specifically so a failure that is caught and handled gracefully — the framework fails open by design — is not also a failure nobody can see. If you are debugging a run that behaved oddly with no corresponding signal, worker logs are the next place to look.