microsoft/TypeScript · error · Error
Expected at least one js file to be emitted or at least one
Error message
Expected at least one js file to be emitted or at least one error to be created.
What it means
Thrown by doJsEmitBaseline in the TypeScript test harness when a compiler-output baseline test produces neither emitted JS nor any diagnostics. The guard at harnessIO.ts:921 fires only when options.noEmit and options.emitDeclarationOnly are both false yet result.js.size === 0 and result.diagnostics.length === 0, i.e. the test asserts the compiler did some real work and it did nothing observable.
Source
Thrown at src/harness/harnessIO.ts:921
const anyUnfoundSources = ts.contains(sourceTDs, /*value*/ undefined);
if (anyUnfoundSources) return "";
const hash = "#base64," + ts.map([outputJSFile.text, sourcemap].concat(sourceTDs.map(td => td!.text)), s => ts.convertToBase64(decodeURIComponent(encodeURIComponent(s)))).join(",");
return "\n//// https://sokra.github.io/source-map-visualization" + hash + "\n";
}
export function doJsEmitBaseline(
baselinePath: string,
header: string,
options: ts.CompilerOptions,
result: CompileFilesResult,
tsConfigFiles: readonly TestFile[],
toBeCompiled: readonly TestFile[],
otherFiles: readonly TestFile[],
harnessSettings: TestCaseParser.CompilerSettings,
): void {
if (!options.noEmit && !options.emitDeclarationOnly && result.js.size === 0 && result.diagnostics.length === 0) {
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
}
// check js output
let tsCode = "";
const tsSources = otherFiles.concat(toBeCompiled);
tsCode += "//// [" + header + "] ////\r\n\r\n";
for (let i = 0; i < tsSources.length; i++) {
tsCode += "//// [" + ts.getBaseFileName(tsSources[i].unitName) + "]\r\n";
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
}
let jsCode = "";
result.js.forEach(file => {
if (jsCode.length && jsCode.charCodeAt(jsCode.length - 1) !== ts.CharacterCodes.lineFeed) {
jsCode += "\r\n";
}
if (!result.diagnostics.length && !ts.endsWith(file.file, ts.Extension.Json)) {
View on GitHub (pinned to b465fdbfe1)
Solutions
- Add `// @noEmit` or `// @emitDeclarationOnly` to the test file's metadata header if the test is intentionally not producing JS — the guard explicitly skips those cases.
- Confirm the test's input files are actually in `toBeCompiled` (not only `otherFiles`) so the compiler emits for them.
- If the test is meant to produce only .d.ts output, route it through the declaration baseline path instead of doJsEmitBaseline.
- Inspect `result.diagnostics` and `result.js` in a debugger to see why both are empty for an emit-on configuration.
Example fix
// before — test header omits emit flags, doJsEmitBaseline throws // @module: commonjs // @Filename: a.ts export const x = 1; // after — declare that no JS emit is expected // @noEmit // @module: commonjs // @Filename: a.ts export const x = 1;
Defensive patterns
Strategy: validation
Validate before calling
// Before invoking doJsEmitBaseline, assert the test will do real work.
function shouldRunJsBaseline(options: ts.CompilerOptions, result: CompileFilesResult): boolean {
if (options.noEmit || options.emitDeclarationOnly) return true; // harness skips these
return result.js.size > 0 || result.diagnostics.length > 0;
}
if (!shouldRunJsBaseline(test.options, test.result)) {
throw new Error("Test mis-configured: enable @noEmit or @emitDeclarationOnly, or ensure inputs produce JS/diagnostics.");
} Type guard
function isEmitProducingResult(result: CompileFilesResult): boolean {
return result.js.size > 0 || result.diagnostics.length > 0;
} Prevention
- Always set @noEmit or @emitDeclarationOnly explicitly in test metadata when the test does not emit JS.
- Keep toBeCompiled non-empty for emit tests; route declaration-only tests through the declaration baseline path.
- Add a pre-flight assertion in test setup that result.js or result.diagnostics is non-empty for emit-on tests.
When it happens
Trigger: Calling doJsEmitBaseline(...) for a test whose CompilerOptions resolve to emit-on, but the CompileFilesResult contains an empty `js` map and zero diagnostics. This happens when a test file is authored for declaration-only or no-emit but its header metadata does not set @noEmit / @emitDeclarationOnly, or when the only output is a source map / d.ts and `result.js` stays empty.
Common situations: A test author copies a declaration-emit test and forgets the `// @emitDeclarationOnly` directive; renaming/refactoring a test so the inputs no longer produce JS; a regression that silently swallows emit; using `// @noEmit` on a test whose harness path still routes through doJsEmitBaseline.
Related errors
- verifyFileContent in file '${fileName}' failed:\n${showTextD
- The baseline file ${relativeFileName} has changed. (Run "her
- New baseline created at ${IO.joinPath("tests", "baselines",
- The generated content was "undefined". Return "null" if no b
- The baseline for ${relativeFileBase} in ${errors.length} fil
AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12).
Data as JSON: /api/errors/7ae7d33f1b146624.
Report an issue: GitHub.