rolldown/rolldown · error
Failed to generate d.ts from runtime-extra-dev.js
Error message
Failed to generate d.ts from runtime-extra-dev.js
What it means
packages/rolldown/build.ts generates TypeScript declarations for the experimental runtime by running the TypeScript compiler over runtime-extra-dev.js. If the emit produces no outputText (the transpile/emit returned nothing usable), the script throws this error to fail the build loudly rather than shipping missing or empty d.ts files.
Solutions
- Verify runtime-extra-dev.js exists at the expected path and is non-empty
- Log the ts.emit/transpile result and diagnostics to find why outputText is empty
- Check the TypeScript version and the compilerOptions used for the emit (target/module must be emit-compatible)
- Re-run the build after fixing; if caused by an upstream change, update generateRuntimeEntry to the new TS API
Example fix
// before
const result = ts.transpileModule(src, { compilerOptions });
if (result.outputText) { /* write */ } else { throw new Error('Failed to generate d.ts from runtime-extra-dev.js'); }
// after: surface diagnostics
const result = ts.transpileModule(src, { compilerOptions, reportDiagnostics: true });
if (result.diagnostics?.length) console.error(result.diagnostics);
if (!result.outputText) throw new Error(`Failed to generate d.ts from runtime-extra-dev.js: ${file} (${src.length} bytes)`); Defensive patterns
Strategy: try-catch
Validate before calling
// before generating, check input exists and is non-empty
if (!fs.existsSync(runtimeExtraDev) || fs.statSync(runtimeExtraDev).size === 0) {
throw new Error(`runtime-extra-dev.js missing or empty at ${runtimeExtraDev}`);
} Try / catch
try {
generateRuntimeEntry();
} catch (e) {
if (String(e).includes('Failed to generate d.ts')) {
console.error('TS emit produced no output; check runtime source and TS version');
process.exit(1);
}
throw e;
} Prevention
- Pin/verify the TypeScript version used by the build
- Log diagnostics from the TS API on every emit
- Keep runtime source paths in one constant module so renames update everywhere
When it happens
Trigger: generateRuntimeEntry calls the TypeScript API on runtime-extra-dev.js and the result's outputText is falsy (emit skipped, wrong input file, or ts configuration mismatch), so the else branch throws.
Common situations: Upgrading TypeScript changes emit behavior; the runtime source file is renamed/moved so the compiled input is empty or wrong; tsconfig options (declaration/emit settings) incompatible with the inline transpile call.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- (dynamic) tsconfig merge warning forwarded as plugin…
- Expected .d.ts files to be chunks, but found asset type for
- No .node files found
- Unresolved module: from
- Warning: Invalid options ( issue found)\n
AI-assisted analysis of rolldown/rolldown@91b44b9d7b (2026-09-07).
Data as JSON: /api/errors/c428d76f4a2bf9bd.
Report an issue: GitHub.
Appendix: source
Thrown at packages/rolldown/build.ts:291
);
const result = ts.transpileDeclaration(commonRuntimeSource, {
compilerOptions: {
...getTsconfigCompilerOptionsForFile(commonRuntimeInputFile),
noEmit: false,
emitDeclarationOnly: true,
},
fileName: commonRuntimeInputFile,
});
if (result && result.outputText) {
fs.writeFileSync(outputFile, result.outputText, 'utf-8');
fs.copyFileSync(
outputFile,
nodePath.resolve(buildMeta.buildOutputDir, 'experimental-runtime-types.d.ts'),
);
} else {
throw new Error('Failed to generate d.ts from runtime-extra-dev.js');
}
}
function readDevRuntimeSources() {
return {
commonRuntimeSource: fs.readFileSync(commonRuntimeInputFile, 'utf-8'),
defaultRuntimeSource: fs.readFileSync(defaultRuntimeInputFile, 'utf-8'),
};
}
function readDefaultDevRuntimeSource() {
const { commonRuntimeSource, defaultRuntimeSource } = readDevRuntimeSources();
return `${commonRuntimeSource}\n${defaultRuntimeSource}`;
}
function getTsconfigCompilerOptionsForFile(file: string) {
const tsconfigPath = ts.findConfigFile(file, (path) => ts.sys.fileExists(path));
let compilerOptions = ts.getDefaultCompilerOptions();View on GitHub (pinned to 91b44b9d7b)