{"record":{"id":"d653e5b5cd6ea56e","repo":"oxc-project/oxc","slug":"unexpected-in-computed-function","errorCode":null,"errorMessage":"Unexpected {} in computed function.","messagePattern":"Unexpected (.+?) in computed function\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/vue/no_async_in_computed_properties.rs","lineNumber":47,"sourceCode":"impl AsyncKind {\n    fn as_str(self) -> &'static str {\n        match self {\n            Self::AsyncFunction => \"async function declaration\",\n            Self::Await => \"await operator\",\n            Self::NewPromise => \"Promise object\",\n            Self::Asynchronous => \"asynchronous action\",\n            Self::Timed => \"timed function\",\n        }\n    }\n}\n\nfn unexpected_in_property(span: Span, kind: AsyncKind, key: &str) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\"Unexpected {} in \\\"{}\\\" computed property.\", kind.as_str(), key))\n        .with_label(span)\n}\n\nfn unexpected_in_function(span: Span, kind: AsyncKind) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\"Unexpected {} in computed function.\", kind.as_str()))\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\nstruct NoAsyncInComputedPropertiesConfig {\n    /// Names of identifiers whose member-call chains (`.then` / `.catch` / `.finally`)\n    /// should be ignored. Useful for libraries like Zod where `.catch(default)` is\n    /// a builder API, not a Promise method.\n    ignored_object_names: FxHashSet<String>,\n}\n\n#[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema)]\npub struct NoAsyncInComputedProperties(Box<NoAsyncInComputedPropertiesConfig>);\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/vue/no_async_in_computed_properties.rs#L29-L65","documentation":"Diagnostic from oxlint's vue/no-async-in-computed-properties rule (since oxlint 1.71.0), function variant. It fires when a computed passed as a standalone function (not an object property with a key) contains asynchronous constructs: async function, await, Promise construction, .then/.catch/.finally chains, or timed functions. Same hazard as the property variant: async computed functions return Promises Vue cannot track, so the UI never updates with the resolved value.","triggerScenarios":"A computed/getter function expression contains `await x`, `new Promise(...)`, `x.then(...)`, or setTimeout, and is reported via unexpected_in_function with the AsyncKind rendered into the message (e.g., 'Unexpected await operator in computed function.').","commonSituations":"Getter-style or functional computed wrappers around async APIs; refactoring property computed into arrow-function computed while keeping an await inside; Promise-method false positives from fluent builder libraries, covered by the rule's ignoredObjectNames option.","solutions":["Make the computed synchronous; trigger the async fetch from watch/watchEffect/onMounted into a ref","Return a synchronous placeholder (loading state) computed from reactive flags instead of awaiting inside","Whitelist builder-API chains via the rule's ignoredObjectNames config when they are not real Promises"],"exampleFix":"// before\nconst fullName = computed(async () => {\n  const profile = await fetchProfile(user.id)\n  return `${user.first} ${profile.last}`\n})\n// after\nconst profile = ref(null)\nwatch(() => user.id, async (id) => { profile.value = await fetchProfile(id) }, { immediate: true })\nconst fullName = computed(() => `${user.first} ${profile.value?.last ?? ''}`)","handlingStrategy":"validation","validationCode":"# scan function-style computed for async constructs\ngrep -rnE \"computed\\((async )?\\(\" --include='*.vue' --include='*.ts' src\ngrep -rn \"computed\" --include='*.vue' src -A8 | grep -E \"await |\\.then\\(|new Promise|setTimeout\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat any await or .then inside a computed as a design smell and move it to a watcher immediately","Store async results in refs; derive synchronous views of them in computed"],"tags":["vue","oxlint","lint","computed","async","reactivity"],"backgroundTag":"async-in-vue-computed","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}