parcel-bundler/parcel · error · ThrowableDiagnostic
Unknown script language: "${script.lang}"
Error message
Unknown script language: "${script.lang}" What it means
Thrown by @parcel/transformer-vue when a <script lang="..."> value does not match the supported cases (empty/js, ts, tsx, coffeescript/coffee). The switch maps known langs to internal asset types; the default branch rejects anything else with a TODO note that no codeframe is attached.
Source
Thrown at packages/transformers/vue/src/VueTransformer.js:320
type = 'js';
break;
case 'jsx':
type = 'jsx';
break;
case 'typescript':
case 'ts':
type = 'ts';
break;
case 'tsx':
type = 'tsx';
break;
case 'coffeescript':
case 'coffee':
type = 'coffee';
break;
default:
// TODO: codeframe
throw new ThrowableDiagnostic({
diagnostic: {
message: md`Unknown script language: "${script.lang}"`,
origin: '@parcel/transformer-vue',
},
});
}
let scriptAsset = {
type,
uniqueKey: asset.id + '-script',
content: script.content,
...(!script.src &&
asset.env.sourceMap && {
map: createMap(script.map, options.projectRoot),
}),
};
return [scriptAsset];
}View on GitHub (pinned to 59484858a1)
Solutions
- Use a supported lang: remove lang for plain JS, or set lang="ts", lang="tsx", or lang="coffee".
- For JSX, use lang="tsx" (TypeScript handles JSX).
- Pre-process the script yourself and drop the unsupported lang attribute.
Example fix
// before <script lang="babel">...</script> // after <script lang="tsx">...</script>
Defensive patterns
Strategy: validation
Validate before calling
const supported = new Set([undefined, '', 'js', 'ts', 'tsx', 'coffeescript', 'coffee']);
if (!supported.has(script.lang)) {
throw new Error(`Unsupported script lang '${script.lang}'; use ts, tsx, coffee, or plain js.`);
} Type guard
const SUPPORTED_SCRIPT_LANGS = new Set([undefined, '', 'js', 'ts', 'tsx', 'coffeescript', 'coffee']);
function isSupportedScriptLang(lang) {
return SUPPORTED_SCRIPT_LANGS.has(lang);
} Prevention
- Use lang="ts" or lang="tsx" for typed/scripted blocks.
- Avoid legacy lang values from other loaders (babel, jsx).
- Drop the lang attribute for plain JavaScript.
When it happens
Trigger: script.lang is set to a value the transformer cannot map (e.g. 'jsx' alone, 'babel', 'ls' for livescript, 'typescript' spelled out).
Common situations: Migrating from vue-loader which accepted 'babel' or 'jsx', copy-pasting lang from another ecosystem, or using a language Parcel's Vue transformer was never taught (e.g. livescript).
Related errors
- Vue config should be an object.
- Unknown style language: "${style.lang}"
- [dynamic diagnostic from Vue compiler parse errors]
- Unknown template language: "${template.lang}"
- [dynamic diagnostic from Vue template compiler errors]
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/e7a201411ccc87e7.
Report an issue: GitHub.