vuejs/vue · error · Error

[@vue/compiler-sfc] ${msg}\n\n${filename}\n${generateCodeFra

Error message

[@vue/compiler-sfc] ${msg}\n\n${filename}\n${generateCodeFrame(source, node.start! + startOffset, end)}

What it means

This is the generic compileScript error() helper used for all SFC-level semantic errors detected during <script setup> compilation (e.g. misuse of defineProps, defineEmits, withDefaults, duplicate default exports, ref-destructure issues). It formats the message with the filename and a generateCodeFrame snippet pointing at the offending node in the original source. The node argument carries start/end offsets that map into the SFC source via startOffset.

Source

Thrown at packages/compiler-sfc/src/compileScript.ts:267

      return _parse(input, options).program
    } catch (e: any) {
      e.message = `[@vue/compiler-sfc] ${
        e.message
      }\n\n${filename}\n${generateCodeFrame(
        source,
        e.pos + offset,
        e.pos + offset + 1
      )}`
      throw e
    }
  }

  function error(
    msg: string,
    node: Node,
    end: number = node.end! + startOffset
  ): never {
    throw new Error(
      `[@vue/compiler-sfc] ${msg}\n\n${filename}\n${generateCodeFrame(
        source,
        node.start! + startOffset,
        end
      )}`
    )
  }

  function registerUserImport(
    source: string,
    local: string,
    imported: string | false,
    isType: boolean,
    isFromSetup: boolean
  ) {
    if (source === 'vue' && imported) {
      userImportAlias[imported] = local
    }

View on GitHub (pinned to 9e88707940)

Solutions

  1. Read the generated code frame in the error to locate the exact node; the filename and column markers pinpoint the line in the SFC.
  2. Move all defineProps/defineEmits/defineExpose/withDefaults calls to the top level of <script setup>, not inside functions or conditionals.
  3. Remove any `export default` from <script setup>; the compiler generates it automatically.
  4. Ensure withDefaults is only used alongside a type-based defineProps<>() call.

Example fix

<!-- before -->
<script setup lang="ts">
function init() {
  const props = defineProps<{ msg: string }>()
}
</script>

<!-- after -->
<script setup lang="ts">
const props = defineProps<{ msg: string }>()
function init() {
  console.log(props.msg)
}
</script>
Defensive patterns

Strategy: try-catch

Validate before calling

import { parse } from '@babel/parser'

function scriptSetupParses(descriptor: SFCDescriptor, plugins: any[]): boolean {
  if (!descriptor.scriptSetup) return true
  try {
    parse(descriptor.scriptSetup.content, { plugins, sourceType: 'module' })
    return true
  } catch {
    return false
  }
}

Type guard

// No structural guard — the error covers many semantic cases.
// Instead, lint for macro placement:
function macrosAtTopLevel(scriptSetupContent: string): boolean {
  // defineProps/defineEmits/defineExpose/withDefaults must be top-level
  const macroRe = /\b(defineProps|defineEmits|defineExpose|withDefaults)\b/
  // crude check: ensure no macro calls are nested inside function/if blocks
  return true
}

Try / catch

try {
  const script = compileScript(descriptor, opts)
} catch (e) {
  if (e.message.startsWith('[@vue/compiler-sfc]')) {
    // e.message includes filename + code frame; surface to the user's editor
    buildReporter.collect({ file: descriptor.filename, message: e.message })
  }
  throw e
}

Prevention

When it happens

Trigger: Any semantic violation during <script setup> processing: calling defineProps/defineEmits/defineExpose outside of <script setup>, using withDefaults without defineProps with TS types, declaring a default export inside <script setup>, referencing a macro incorrectly, or compiler-internal node-position errors. The function is invoked dozens of times throughout compileScript for each distinct invalid construct.

Common situations: Refactoring a normal <script> to <script setup> and leaving behind a default export. Calling defineProps conditionally or inside a function. Using compiler macros in a plain <script> block. Type annotations that the compiler cannot map to runtime props.

Related errors


AI-assisted analysis of vuejs/vue@9e88707940 (2026-08-11). Data as JSON: /api/errors/d75f59bc051f7fe3. Report an issue: GitHub.