microsoft/playwright · error · Error
path is not available in the browser
Error message
path is not available in the browser
What it means
Thrown by the browser-bundle stub of Node's `path` module: calling `path.dirname`, `basename`, `resolve`, `join`, `relative`, or `isAbsolute` invokes `notAvailable()` which throws. Only `path.sep` (`'/'`) is defined; all functional exports throw immediately.
Source
Thrown at packages/playwright-client/src/nodeStubs/path.ts:18
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function notAvailable(): never {
throw new Error('path is not available in the browser');
}
export const sep = '/';
export const dirname: any = notAvailable;
export const basename: any = notAvailable;
export const resolve: any = notAvailable;
export const join: any = notAvailable;
export const relative: any = notAvailable;
export const isAbsolute: any = notAvailable;
export default { sep, dirname, basename, resolve, join, relative, isAbsolute };
View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Gate path operations behind a Node-only code path and avoid importing `path` in the browser bundle.
- Replace simple join/normalize logic with template strings or a tiny browser-safe helper.
- Mark `path` as external for the Node build target so it is not replaced by the stub.
Example fix
// before
import path from 'path';
const full = path.join(base, file); // throws in browser bundle
// after
const full = typeof window === 'undefined'
? (await import('path')).join(base, file)
: `${base}/${file}`; Defensive patterns
Strategy: type-guard
Validate before calling
function safePathJoin(...segs: string[]): string {
if (typeof window !== 'undefined') return segs.join('/');
return require('path').join(...segs);
} Type guard
function pathAvailable(): boolean {
return typeof window === 'undefined' && typeof process !== 'undefined' && !!process.versions?.node;
} Try / catch
try {
return path.join(...segs);
} catch (e) {
if (/path is not available in the browser/.test(e.message)) {
return seggs.join('/');
}
throw e;
} Prevention
- Use a tiny browser-safe join helper in shared code.
- Externalize `path` for Node targets so the stub is not substituted.
- Split path logic into platform-specific modules.
When it happens
Trigger: Code resolved to `packages/playwright-client/src/nodeStubs/path.ts` (the browser client bundle) that calls any path utility: `path.join(...)`, `path.resolve(...)`, `path.dirname(...)`, etc.
Common situations: Shared path-handling code bundled into the browser client; a dependency that requires `path` at runtime; bundler aliasing `path` to the stub for the browser target.
Related errors
- fs is not available in the browser
- No devices found
- Cannot launch Firefox with relative home directory. Did you
- Unable to open X display! ================================ M
- Unsupported platform: ${process.platform}
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/58c8a6508e671fa2.
Report an issue: GitHub.