{"record":{"id":"f9871382e95e5a49","repo":"vuejs/core","slug":"vue-compiler-sfc-script-and-script-setup-mu","errorCode":null,"errorMessage":"[@vue/compiler-sfc] <script> and <script setup> must have the same language type.","messagePattern":"\\[@vue/compiler-sfc\\] <script> and <script setup> must have the same language type\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/compiler-sfc/src/compileScript.ts","lineNumber":189,"sourceCode":"): SFCScriptBlock {\n  if (!options.id) {\n    warnOnce(\n      `compileScript now requires passing the \\`id\\` option.\\n` +\n        `Upgrade your vite or vue-loader version for compatibility with ` +\n        `the latest experimental proposals.`,\n    )\n  }\n\n  const { script, scriptSetup, source, filename } = sfc\n  const hoistStatic = options.hoistStatic !== false && !script\n  const scopeId = options.id ? options.id.replace(/^data-v-/, '') : ''\n  const scriptLang = script && script.lang\n  const scriptSetupLang = scriptSetup && scriptSetup.lang\n  const isJSOrTS =\n    isJS(scriptLang, scriptSetupLang) || isTS(scriptLang, scriptSetupLang)\n\n  if (script && scriptSetup && scriptLang !== scriptSetupLang) {\n    throw new Error(\n      `[@vue/compiler-sfc] <script> and <script setup> must have the same ` +\n        `language type.`,\n    )\n  }\n\n  if (!scriptSetup) {\n    if (!script) {\n      throw new Error(`[@vue/compiler-sfc] SFC contains no <script> tags.`)\n    }\n\n    // normal <script> only\n    if (script.lang && !isJSOrTS) {\n      // do not process non js/ts script blocks\n      return script\n    }\n\n    const ctx = new ScriptCompileContext(sfc, options)\n    return processNormalScript(ctx, scopeId)","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/vuejs/core/blob/a2b40db9a83b36ed9da3a16403cf8f040262d73f/packages/compiler-sfc/src/compileScript.ts#L171-L207","documentation":"Thrown by compileScript in @vue/compiler-sfc when an SFC declares BOTH a normal <script> block and a <script setup> block but their lang attributes differ. Vue merges the two blocks into one module, so they must compile under the same language pipeline. The check at compileScript.ts:189 compares script.lang against scriptSetup.lang and aborts before any transformation runs.","triggerScenarios":"An .vue file containing e.g. <script lang=\"ts\"> and <script setup lang=\"tsx\">, or <script> (no lang, JS) next to <script setup lang=\"ts\">. Calling compileScript(sfc, options) on such an SFC reproduces it.","commonSituations":"Mixing a TypeScript <script setup> with a plain JS <script> for non-setup exports; copy-pasting a script block from another SFC with a different lang; tooling that injects a <script> block with a default lang.","solutions":["Make both <script> and <script setup> use the same lang attribute (usually both lang=\"ts\").","If the normal <script> only exists for side-effect imports or options that belong in setup, move that content into <script setup> and remove the duplicate block.","If you genuinely need two languages, split the logic into a separate imported .ts/.js module instead of a second SFC script block."],"exampleFix":"// before\n<script lang=\"ts\">\nexport default { inheritAttrs: false }\n</script>\n<script setup lang=\"tsx\">\n// ...\n</script>\n\n// after\n<script lang=\"ts\">\nexport default { inheritAttrs: false }\n</script>\n<script setup lang=\"ts\">\n// ...\n</script>","handlingStrategy":"validation","validationCode":"// Before compileScript, verify both script blocks share a lang.\nfunction canCompileScript(sfc: { script?: { lang?: string }; scriptSetup?: { lang?: string } }) {\n  if (sfc.script && sfc.scriptSetup) {\n    const a = sfc.script.lang || ''\n    const b = sfc.scriptSetup.lang || ''\n    if (a !== b) return false\n  }\n  return true\n}","typeGuard":"function scriptLangsMatch(sfc: { script?: { lang?: string }; scriptSetup?: { lang?: string } }): boolean {\n  if (!sfc.script || !sfc.scriptSetup) return true\n  return (sfc.script.lang || '') === (sfc.scriptSetup.lang || '')\n}","tryCatchPattern":null,"preventionTips":["Pick one lang (usually 'ts') for all script blocks in an SFC.","Lint .vue files with eslint-plugin-vue to catch mismatched script lang early.","In SFC pipelines, short-circuit compileScript when langs differ and report a clear source-span error."],"tags":["vue","compiler-sfc","script-setup","sfc","configuration"],"backgroundTag":null,"analyzedSha":"a2b40db9a83b36ed9da3a16403cf8f040262d73f","analyzedAt":"2026-08-12T14:21:14.989Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}