microsoft/TypeScript · error · Error
tracing requires having fs\n(original error: ${e.message ||
Error message
tracing requires having fs\n(original error: ${e.message || e}) What it means
Thrown by `ts.startTracing` when it cannot `require("fs")`. Tracing writes JSON traces to disk and needs the Node `fs` module; if `require("fs")` throws (bundled compiler build, sandboxed/blocked require, non-Node host), `startTracing` aborts. The original error is appended to the message.
Source
Thrown at src/compiler/tracing.ts:66
let legendPath: string | undefined;
const legend: TraceRecord[] = [];
// The actual constraint is that JSON.stringify be able to serialize it without throwing.
interface Args {
[key: string]: string | number | boolean | null | undefined | Args | readonly (string | number | boolean | null | undefined | Args)[]; // eslint-disable-line no-restricted-syntax
}
/** Starts tracing for the given project. */
export function startTracing(tracingMode: Mode, traceDir: string, configFilePath?: string): void {
Debug.assert(!tracing, "Tracing already started");
if (fs === undefined) {
try {
fs = require("fs");
}
catch (e) {
throw new Error(`tracing requires having fs\n(original error: ${e.message || e})`);
}
}
mode = tracingMode;
typeCatalog.length = 0;
if (legendPath === undefined) {
legendPath = combinePaths(traceDir, "legend.json");
}
// Note that writing will fail later on if it exists and is not a directory
if (!fs.existsSync(traceDir)) {
fs.mkdirSync(traceDir, { recursive: true });
}
const countPart = mode === "build" ? `.${process.pid}-${++traceCount}`
: mode === "server" ? `.${process.pid}`
: ``;
View on GitHub (pinned to b465fdbfe1)
Solutions
- Do not enable tracing in environments without `fs` (gate it behind a runtime check).
- Provide an `fs` shim or externalize `fs` as a bundler externals entry.
- Run tracing in a plain Node process instead of a bundled one.
- If you control the call site, check `typeof require !== "undefined"` and that `require("fs")` succeeds before calling `startTracing`.
Example fix
// before
ts.startTracing(ts.Mode.All, traceDir, configPath); // throws in a bundle w/o fs
// after
try { require("fs"); ts.startTracing(ts.Mode.All, traceDir, configPath); }
catch { /* tracing unavailable in this host; skip */ } Defensive patterns
Strategy: validation
Validate before calling
let fsAvailable = false;
try { require("fs"); fsAvailable = true; } catch {}
// only call startTracing when fsAvailable is true Type guard
function canTrace(): boolean { try { require("fs"); return true; } catch { return false; } } Prevention
- Mark `fs` as external when bundling the compiler.
- Gate tracing behind a runtime `require("fs")` probe.
- Run `--generateTrace` in a standard Node process.
When it happens
Trigger: Calling `ts.startTracing(mode, traceDir, configPath)` (directly, or via `--traceResolution`/`--generateTrace` style flows that reach it) in an environment where `fs` is unavailable: a webpack/esbuild bundle of the compiler, a sandbox that blocks built-ins, or a custom host without Node's loader.
Common situations: Bundling the TS compiler for browser/electron use and then enabling tracing; running the compiler under a custom loader that intercepts `require`; CI sandboxes that restrict built-in modules.
Related errors
- Function expected
- Cannot add initializers after decoration has completed
- Object expected
- Symbol.asyncIterator is not defined.
- Class extends value ${String(b)} is not a constructor or nul
AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12).
Data as JSON: /api/errors/25df417ddc8ff9f2.
Report an issue: GitHub.