What it measures
The signal throws a single synthetic Error and inspects properties of the resulting instance to classify the host JavaScript engine family. The classification result is engine-bound: Chrome and Safari running on the same machine produce different engine identifications because the underlying engines expose different non-standard Error API surfaces.
This is one of several independent engine-reveal vectors in the library. Each vector probes a structurally different surface, so a spoofer that patches one vector still surfaces through the others. An anti-detect tool would have to coordinate all of them simultaneously to evade detection.
The result feeds an engine-vs-UA cross-check in the consistency layer. A spoofer claiming a browser whose engine identification does not match the underlying engine surfaces produces a flag without breaking the user-visible page.
How it's collected
The collector performs a small synchronous probe — no DOM, no network, no async — and folds a small number of boolean / categorical reads into a stable hash. The exact properties probed, the priority order in which they are evaluated, the engine-label vocabulary, and the hash-input composition are part of the internal recipe and not part of the public contract.
The probe is sub-millisecond and safe under strict Content Security Policy environments. The probe contents do not depend on file paths, line numbers, or page URLs, so the hash is stable across call-site contexts.
Confidence rules
| Confidence | Trigger |
|---|---|
| normal | Classifier returned an engine label, including the catch-all label for unrecognised engines. The boolean property reads alone carry entropy. |
| absent | The outer try/catch fired (for example, the Error constructor was replaced with one that itself throws); sentinel: 'threw'. |
Why engine-bound
The Error-instance shape is emitted by the JavaScript engine at throw time, not by hardware or the operating system. Different browsers shipped by different engine teams expose different non-standard properties on the Error object and produce a different stack-string shape. Including the signal in the hardware-only fingerprint would shatter cross-browser stability — a visitor switching browsers on the same machine would produce a different hardware fingerprint even though the device is unchanged.
Because the variation is purely engine-driven, the hash is stable within an engine family across browser versions, page loads, and pages on the same origin. That is the defining property of an engine-bound signal.
Things worth knowing
- Hash inputs are stack-content-independent. File paths, line numbers, message text, and other call-site-specific data do not enter the hash; only properties of the Error instance and a small set of derived booleans do.
- The signal has no 'degraded' or 'stabilized' confidence state. It is either 'normal' or 'absent'.
- On iOS, every browser engine is WebKit-based regardless of the UA-string brand. The cross-check in the consistency layer accounts for this so that, for example, Chrome-on-iOS is not flagged as a spoofer for producing the WebKit engine identification.
- DevTools injection and strict CSP environments do not affect the probe.
Last reviewed 2026-06-04

