{"record":{"id":"2ca2490272dd6e20","repo":"oxc-project/oxc","slug":"name-is-forbidden-after-an-await-expression","errorCode":null,"errorMessage":"`{name}` is forbidden after an `await` expression.","messagePattern":"`(.+?)` is forbidden after an `await` expression\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/vue/no_expose_after_await.rs","lineNumber":18,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{\n        ArrowFunctionExpression, AwaitExpression, BindingPattern, CallExpression, ChainElement,\n        ExportDefaultDeclarationKind, Expression, Function, ObjectExpression, ObjectPropertyKind,\n        Program, Statement,\n    },\n};\nuse oxc_ast_visit::{VisitJs, walk_js};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::{ScopeFlags, Scoping, SymbolId};\nuse oxc_span::Span;\n\nuse crate::{AstNode, context::LintContext, frameworks::FrameworkOptions, rule::Rule};\n\nfn no_expose_after_await_diagnostic(span: Span, name: &str) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\"`{name}` is forbidden after an `await` expression.\"))\n        .with_help(\n            \"`expose` should be called synchronously in `setup()` \\\n            (or `defineExpose()` in `<script setup>`). Move the call before the first `await`.\",\n        )\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoExposeAfterAwait;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow asynchronously registered `expose`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// `defineExpose` and `context.expose()` registered after an `await`","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/vue/no_expose_after_await.rs#L1-L36","documentation":"The vue/no-expose-after-await rule fires when `expose()` (Options API `setup(context)`) or `defineExpose()` (`<script setup>`) is called after an `await` expression in async setup logic. Vue resolves the component's exposed object during synchronous setup; exposing after an await means the parent may already hold a reference and the exposed contract is not in place. The rule's help text directs you to move the call before the first `await`.","triggerScenarios":"In `<script setup>`: `await fetch(...); defineExpose({ reload });`. In Options API `setup()`: `await something(); context.expose({ ... })`. The rule resolves the callee symbol (ScopeFlags/SymbolId are used to match the call) so any awaited statement followed by expose/defineExpose triggers it.","commonSituations":"Data-fetching components that load remote config before exposing methods; refactoring sync setup into async without reordering; components using top-level await in `<script setup>` (which requires Suspense).","solutions":["Move the `defineExpose(...)` / `context.expose(...)` call to the top of setup, before the first `await`.","If the exposed values depend on awaited data, expose stable references (e.g. a reactive object or methods) up front and mutate them after the await completes.","Consider moving async work into `onMounted` or a composable so setup stays synchronous.","Re-run oxlint to confirm the call now precedes every await."],"exampleFix":"// before\n<script setup>\nconst data = await loadData();\ndefineExpose({ data }); // forbidden after an `await` expression\n</script>\n\n// after\n<script setup>\nconst data = ref(null);\ndefineExpose({ data });\ndata.value = await loadData();\n</script>","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat 'defineExpose/expose first, await later' as a hard ordering rule in setup.","Expose refs/methods up front and fill data after awaits complete.","Enable vue/no-expose-after-await in CI so reordering mistakes fail the build.","Review any PR that introduces top-level await into setup."],"tags":["vue","async-await","script-setup","lint","expose"],"backgroundTag":"async-setup-order","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}