microsoft/playwright · error · Error
Route from har is not supported in thin clients
Error message
Route from har is not supported in thin clients
What it means
Thrown by BrowserContext.routeFromHAR() when the connection's localUtils() is null, which happens in thin/remote clients. HAR routing requires the LocalUtils server-side object to parse and serve the HAR file; thin clients don't host it. The guard is `if (!localUtils)`.
Solutions
- Run the browser locally (launch/launchPersistentContext) where localUtils is present.
- On the remote server, ensure a full (non-thin) Playwright build is serving the connection.
- Replace HAR routing with route() handlers that don't need localUtils.
Example fix
// before
const browser = await playwright.chromium.connect(wsEndpoint);
const ctx = await browser.newContext();
await ctx.routeFromHAR('rec.har');
// after
const browser = await playwright.chromium.launch();
const ctx = await browser.newContext();
await ctx.routeFromHAR('rec.har'); Defensive patterns
Strategy: type-guard
Validate before calling
const localUtils = (context as any)._connection?.localUtils?.();
if (!localUtils)
throw new Error('routeFromHAR requires a local (non-thin) connection.'); Type guard
function supportsHarRouting(ctx: any): boolean {
return !!ctx?._connection?.localUtils?.();
} Prevention
- Prefer local launch when HAR routing is required.
- Detect thin-client mode and degrade to route() handlers.
When it happens
Trigger: Calling `context.routeFromHAR('rec.har')` after connecting via BrowserType.connect() to a remote endpoint, or in playwright-client thin mode. localUtils() returns null because the LocalUtils object lives only on the host that owns the registry.
Common situations: Moving tests from local launch to a remote browser grid (Browserless, internal Selenium grid) without realizing HAR routing needs host-side support; mixing thin client with full client features.
Related errors
- Another client is already routing WebSockets
- Cannot transfer files larger than 50Mb to a browser not…
- Connecting to Android devices is not allowed.
- Error: unable to connect to a browser that does not have…
- Found redirect cycle for
AI-assisted analysis of microsoft/playwright@500c9c822c (2026-08-12).
Data as JSON: /api/errors/45a7ceab91e417bb.
Report an issue: GitHub.
Appendix: source
Thrown at packages/playwright-core/src/client/browserContext.ts:413
this._bindings.set(name, binding);
return DisposableObject.from(result.disposable);
}
async route(url: URLMatch, handler: network.RouteHandlerCallback, options: { times?: number } = {}): Promise<DisposableStub> {
this._routes.unshift(new network.RouteHandler(this._options.baseURL, url, handler, options.times));
await this._updateInterceptionPatterns({ title: 'Route requests' });
return new DisposableStub(() => this.unroute(url, handler));
}
async routeWebSocket(url: URLMatch, handler: network.WebSocketRouteHandlerCallback): Promise<void> {
this._webSocketRoutes.unshift(new network.WebSocketRouteHandler(this._options.baseURL, url, handler));
await this._updateWebSocketInterceptionPatterns({ title: 'Route WebSockets' });
}
async routeFromHAR(har: string, options: { url?: string | RegExp, notFound?: 'abort' | 'fallback', update?: boolean, updateContent?: 'attach' | 'embed', updateMode?: 'minimal' | 'full' } = {}): Promise<void> {
const localUtils = this._connection.localUtils();
if (!localUtils)
throw new Error('Route from har is not supported in thin clients');
if (options.update) {
await this.tracing._recordIntoHAR(har, null, options);
return;
}
const harRouter = await HarRouter.create(localUtils, har, options.notFound || 'abort', { urlMatch: options.url });
this._harRouters.push(harRouter);
await harRouter.addContextRoute(this);
}
private _disposeHarRouters() {
this._harRouters.forEach(router => router.dispose());
this._harRouters = [];
}
async unrouteAll(options?: { behavior?: 'wait'|'ignoreErrors'|'default' }): Promise<void> {
await this._unrouteInternal(this._routes, [], options?.behavior);
this._disposeHarRouters();
}View on GitHub (pinned to 500c9c822c)