parcel-bundler/parcel · error · ThrowableDiagnostic
Declared output format "${descriptor.outputFormat}" does not
Error message
Declared output format "${descriptor.outputFormat}" does not match expected output format "${inferredOutputFormat}". What it means
Parcel infers the correct outputFormat from the distEntry extension and package.json `type` field. If you explicitly set `descriptor.outputFormat` and it disagrees with the inferred format, the build aborts. The expected extensions per format are listed (.mjs/.js for esmodule, .cjs/.js for commonjs, .js for global).
Source
Thrown at packages/core/core/src/requests/TargetRequest.js:1280
typeof pkgContents === 'string'
? pkgContents
: // $FlowFixMe
JSON.stringify(pkgContents, null, '\t');
let expectedExtensions;
switch (descriptor.outputFormat) {
case 'esmodule':
expectedExtensions = ['.mjs', '.js'];
break;
case 'commonjs':
expectedExtensions = ['.cjs', '.js'];
break;
case 'global':
expectedExtensions = ['.js'];
break;
}
// $FlowFixMe
let listFormat = new Intl.ListFormat('en-US', {type: 'disjunction'});
throw new ThrowableDiagnostic({
diagnostic: {
message: md`Declared output format "${descriptor.outputFormat}" does not match expected output format "${inferredOutputFormat}".`,
origin: '@parcel/core',
codeFrames: [
{
language: 'json',
filePath: pkgFilePath ?? undefined,
code: contents,
codeHighlights: generateJSONCodeHighlights(contents, [
{
key: `/targets/${targetName}/outputFormat`,
type: 'value',
message: 'Declared output format defined here',
},
{
key: nullthrows(inferredOutputFormatField),
type: 'value',
message: 'Inferred output format defined here',View on GitHub (pinned to 59484858a1)
Solutions
- Align the explicit outputFormat with the extension (e.g. esmodule + .mjs, commonjs + .cjs).
- Remove the explicit outputFormat and let Parcel infer it from the extension/type.
- Adjust the extension or `"type"` field to match the desired format.
Example fix
// before (package.json)
{
"main": "dist/index.cjs",
"targets": { "main": { "outputFormat": "esmodule" } }
}
// after
{
"main": "dist/index.mjs",
"targets": { "main": { "outputFormat": "esmodule" } }
} Defensive patterns
Strategy: validation
Validate before calling
function inferFormat(entry, pkgType) {
if (entry.endsWith('.mjs')) return 'esmodule';
if (entry.endsWith('.cjs')) return 'commonjs';
return pkgType === 'module' ? 'esmodule' : 'commonjs';
}
function assertFormatMatches(targets, pkg) {
for (const [name, d] of Object.entries(targets || {})) {
if (!d.outputFormat) continue;
const inferred = inferFormat(d.distEntry || pkg[name], pkg.type);
if (d.outputFormat !== inferred) {
throw new Error(`Target ${name}: outputFormat ${d.outputFormat} != inferred ${inferred}`);
}
}
} Type guard
function outputFormatCoherent(d, inferred) {
return d.outputFormat == null || d.outputFormat === inferred;
} Try / catch
try { await parcel.run(); } catch (e) {
if (/does not match expected output format/.test(e.message)) {
console.error('Align explicit outputFormat with extension/package type.');
} else throw e;
} Prevention
- Omit outputFormat and let Parcel infer from extension/type.
- When setting outputFormat, change the extension to match.
- Document the extension↔format mapping in shared config.
When it happens
Trigger: Setting `targets.<name>.outputFormat` to a value that conflicts with the extension/type-derived format for that target's distEntry.
Common situations: Hardcoding outputFormat while changing extensions; package.json `"type": "module"` interacting with a `commonjs` outputFormat setting; partial config migrations where format and extension drift apart.
Related errors
- Unexpected output file type ${ext} in target "${targetName}"
- The "global" output format is not supported in the "${target
- Library targets are not supported in serve mode.
- Scope hoisting cannot be disabled for library targets.
- Invalid distPath for target "${targetName}"
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/436bd71322329b9f.
Report an issue: GitHub.