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

  1. Use a supported lang: remove lang for plain JS, or set lang="ts", lang="tsx", or lang="coffee".
  2. For JSX, use lang="tsx" (TypeScript handles JSX).
  3. 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

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


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/e7a201411ccc87e7. Report an issue: GitHub.