Skip to content

fix(runtime-core): prevent instance leak in withAsyncContext - #14445

Merged
edison1105 merged 2 commits into
mainfrom
edison/fix/effectScopeMemoryLeak
Feb 24, 2026
Merged

fix(runtime-core): prevent instance leak in withAsyncContext#14445
edison1105 merged 2 commits into
mainfrom
edison/fix/effectScopeMemoryLeak

Conversation

@edison1105

@edison1105 edison1105 commented Feb 11, 2026

Copy link
Copy Markdown
Member

fix nuxt/nuxt#33644 (comment)
schedule withAsyncContext reset after restore to prevent scope leaks

Summary by CodeRabbit

  • Bug Fixes

    • Prevented component instance exposure during asynchronous setup flows, ensuring instance state is cleaned up promptly after async operations.
  • Tests

    • Added tests verifying instance scope is properly restored/cleared across concurrent and asynchronous restore scenarios.

schedule withAsyncContext reset after restore to prevent scope leaks
@coderabbitai

coderabbitai Bot commented Feb 11, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Defers component-instance restoration and adds cleanup scheduling in withAsyncContext to prevent instance leakage during async restores; adds tests that assert no instance leakage in microtasks and concurrent restores.

Changes

Cohort / File(s) Summary
Test Additions
packages/runtime-core/__tests__/apiSetupHelpers.spec.ts
Adds tests: "should not leak instance to user microtasks after restore" and "should not leak sibling instance in concurrent restores"; strengthens existing error-handling test to assert instance scope cleanup after async ticks.
Instance Context Restoration
packages/runtime-core/src/apiSetupHelpers.ts
Introduces a dedicated cleanup() routine and defers restoration/cleanup to the next microtask (scheduling via Promise) instead of immediate restoration; catch paths now schedule cleanup for the continuation to avoid restoring a captured instance during concurrent async flows.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hop through promises, tidy and spry,

I nudge the restore to the next micro-sky,
No stray instance left where it shouldn't be,
Concurrent restores now safe as can be — hooray for me! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The code changes address the memory leak reported in issue #33644 by implementing proper cleanup in withAsyncContext to prevent scope leaks during async operations.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the async setup instance scope leak; test additions and implementation changes directly target the identified memory leak issue.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title 'fix(runtime-core): prevent instance leak in withAsyncContext' directly and clearly summarizes the main change - fixing a memory leak in the withAsyncContext function by preventing instance leaks.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch edison/fix/effectScopeMemoryLeak

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Feb 11, 2026

Copy link
Copy Markdown

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 104 kB (+123 B) 39.3 kB (+33 B) 35.4 kB (+49 B)
vue.global.prod.js 162 kB (+123 B) 59.4 kB (+38 B) 52.8 kB (+74 B)

Usages

Name Size Gzip Brotli
createApp (CAPI only) 47.8 kB 18.6 kB 17.1 kB
createApp 56 kB 21.7 kB 19.8 kB
createSSRApp 60.2 kB 23.4 kB 21.4 kB
defineCustomElement 61.6 kB 23.4 kB 21.4 kB
overall 70.4 kB 27 kB 24.6 kB

@pkg-pr-new

pkg-pr-new Bot commented Feb 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

@vue/compiler-core

pnpm add https://pkg.pr.new/@vue/compiler-core@14445
npm i https://pkg.pr.new/@vue/compiler-core@14445
yarn add https://pkg.pr.new/@vue/compiler-core@14445.tgz

@vue/compiler-dom

pnpm add https://pkg.pr.new/@vue/compiler-dom@14445
npm i https://pkg.pr.new/@vue/compiler-dom@14445
yarn add https://pkg.pr.new/@vue/compiler-dom@14445.tgz

@vue/compiler-sfc

pnpm add https://pkg.pr.new/@vue/compiler-sfc@14445
npm i https://pkg.pr.new/@vue/compiler-sfc@14445
yarn add https://pkg.pr.new/@vue/compiler-sfc@14445.tgz

@vue/compiler-ssr

pnpm add https://pkg.pr.new/@vue/compiler-ssr@14445
npm i https://pkg.pr.new/@vue/compiler-ssr@14445
yarn add https://pkg.pr.new/@vue/compiler-ssr@14445.tgz

@vue/reactivity

pnpm add https://pkg.pr.new/@vue/reactivity@14445
npm i https://pkg.pr.new/@vue/reactivity@14445
yarn add https://pkg.pr.new/@vue/reactivity@14445.tgz

@vue/runtime-core

pnpm add https://pkg.pr.new/@vue/runtime-core@14445
npm i https://pkg.pr.new/@vue/runtime-core@14445
yarn add https://pkg.pr.new/@vue/runtime-core@14445.tgz

@vue/runtime-dom

pnpm add https://pkg.pr.new/@vue/runtime-dom@14445
npm i https://pkg.pr.new/@vue/runtime-dom@14445
yarn add https://pkg.pr.new/@vue/runtime-dom@14445.tgz

@vue/server-renderer

pnpm add https://pkg.pr.new/@vue/server-renderer@14445
npm i https://pkg.pr.new/@vue/server-renderer@14445
yarn add https://pkg.pr.new/@vue/server-renderer@14445.tgz

@vue/shared

pnpm add https://pkg.pr.new/@vue/shared@14445
npm i https://pkg.pr.new/@vue/shared@14445
yarn add https://pkg.pr.new/@vue/shared@14445.tgz

vue

pnpm add https://pkg.pr.new/vue@14445
npm i https://pkg.pr.new/vue@14445
yarn add https://pkg.pr.new/vue@14445.tgz

@vue/compat

pnpm add https://pkg.pr.new/@vue/compat@14445
npm i https://pkg.pr.new/@vue/compat@14445
yarn add https://pkg.pr.new/@vue/compat@14445.tgz

commit: 62fa082

@edison1105 edison1105 added the ❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. label Feb 11, 2026
@edison1105

Copy link
Copy Markdown
Member Author

/ecosystem-ci run

@edison1105 edison1105 changed the title fix(runtime-core): balance async setup instance scope restore/reset fix(runtime-core): prevent instance leak in withAsyncContext Feb 12, 2026
@vue-bot

vue-bot commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

📝 Ran ecosystem CI: Open

suite result latest scheduled
pinia success success
radix-vue success success
quasar success success
vitepress success success
vite-plugin-vue success success
primevue success success
nuxt success success
language-tools success success
vant success success
vue-i18n success success
router failure failure
vueuse success success
vue-macros success success
vuetify success success
vue-simple-compiler success success
test-utils success success

@vuejs vuejs deleted a comment from edison1105 Feb 12, 2026
@SebbeJohansson

Copy link
Copy Markdown

@edison1105 when do you think this could be included in a release? Waiting for this to be included upstream in nuxt.

@edison1105
edison1105 merged commit 702284f into main Feb 24, 2026
16 checks passed
@edison1105
edison1105 deleted the edison/fix/effectScopeMemoryLeak branch February 24, 2026 03:40
ahacop added a commit to changebot-ai/widgets that referenced this pull request Aug 24, 2026
[cb skip]

vue is a dev dependency of @changebot/widgets-vue. The peer range
stays ^3.0.0.

== [3.5.41](vuejs/core@v3.5.40...v3.5.41) (2026-08-05)

== Bug Fixes

* **compiler-core:** preserve vnode lifecycle in stable v-for ([#11682](vuejs/core#11682)) ([02421cd](vuejs/core@02421cd)), closes [#9239](vuejs/core#9239) [#12569](vuejs/core#12569)
* **compiler-sfc:** handle transformed template AST after cache invalidation ([#15136](vuejs/core#15136)) ([a4440c0](vuejs/core@a4440c0)), closes [#15126](vuejs/core#15126) [#15128](vuejs/core#15128)
* **custom-element:** preserve nested async mount order ([#15154](vuejs/core#15154)) ([71f9ff5](vuejs/core@71f9ff5)), closes [#15153](vuejs/core#15153)
* **custom-element:** warn when props override native properties ([#12125](vuejs/core#12125)) ([22b53ea](vuejs/core@22b53ea)), closes [#12124](vuejs/core#12124)
* **runtime-core:** avoid re-fetching resource props with unchanged values ([#15105](vuejs/core#15105)) ([a7513a1](vuejs/core@a7513a1))
* **runtime-core:** restore SSR setup state when handling async setup result ([#15114](vuejs/core#15114)) ([b6191cb](vuejs/core@b6191cb)), closes [#15113](vuejs/core#15113)
* **scheduler:** avoid stack overflow when flushing very large post cb arrays ([#15143](vuejs/core#15143)) ([c04a45d](vuejs/core@c04a45d)), closes [#15142](vuejs/core#15142)
* **slots:** handle nullish v-bind slot props ([#15177](vuejs/core#15177)) ([2506700](vuejs/core@2506700))
* **ssr:** normalize hidden states during hydration ([#13125](vuejs/core#13125)) ([4e467d7](vuejs/core@4e467d7))
* **transition:** support transition to teleport component child ([#11959](vuejs/core#11959)) ([77061fe](vuejs/core@77061fe)), closes [#11910](vuejs/core#11910)
* **types:** preserve defineModel inference with factory defaults ([#15097](vuejs/core#15097)) ([0516c43](vuejs/core@0516c43)), closes [#15096](vuejs/core#15096)
* **v-model:** preserve text input before hydration ([#14411](vuejs/core#14411)) ([2468464](vuejs/core@2468464)), closes [#14403](vuejs/core#14403)

== [3.5.40](vuejs/core@v3.5.39...v3.5.40) (2026-07-16)

== Bug Fixes

* **compiler-core:** avoid leaking slot branch keys ([#15051](vuejs/core#15051)) ([20c9d26](vuejs/core@20c9d26)), closes [#15048](vuejs/core#15048)
* **hydration:** pass namespace when patching dynamic props ([#15082](vuejs/core#15082)) ([e0d2723](vuejs/core@e0d2723)), closes [#15081](vuejs/core#15081) [#15050](vuejs/core#15050)
* **reactivity:** handle effect removal during scope stop ([#15084](vuejs/core#15084)) ([378f978](vuejs/core@378f978)), closes [#15083](vuejs/core#15083)
* **runtime-core:** skip lazy hydration for detached roots ([#15092](vuejs/core#15092)) ([97f3525](vuejs/core@97f3525)), closes [#15091](vuejs/core#15091)
* **runtime-core:** unwind dangling blocks when slot content throws ([#15071](vuejs/core#15071)) ([ddc132d](vuejs/core@ddc132d)), closes [#15070](vuejs/core#15070)
* **runtime-dom:** respect current select model type ([#15010](vuejs/core#15010)) ([eb89e93](vuejs/core@eb89e93)), closes [#15009](vuejs/core#15009)
* **server-renderer:** handle errors in optimized component renders ([#12601](vuejs/core#12601)) ([474907c](vuejs/core@474907c)), closes [#12575](vuejs/core#12575)
* **server-renderer:** remove package dependency cycle ([#15063](vuejs/core#15063)) ([4d35eca](vuejs/core@4d35eca))
* **shared:** prevent SSR comment escaping from creating closing delimiters ([#15045](vuejs/core#15045)) ([bd962bb](vuejs/core@bd962bb))
* **types:** don't constrain component $el type to Element ([#15040](vuejs/core#15040)) ([164460a](vuejs/core@164460a))

== [3.5.39](vuejs/core@v3.5.38...v3.5.39) (2026-06-25)


== Bug Fixes

* **compiler-core:** correct filter rewrite recursion ([#14959](vuejs/core#14959)) ([be7ce31](vuejs/core@be7ce31))
* **hydration:** force patch dynamic props when hydrating ([#9083](vuejs/core#9083)) ([024cf06](vuejs/core@024cf06)), closes [#9033](vuejs/core#9033)
* **hydration:** respect data-allow-mismatch on conditional branches ([#12801](vuejs/core#12801)) ([164af63](vuejs/core@164af63)), closes [#12782](vuejs/core#12782)
* **reactivity:** avoid triggering effects when set fails ([#14964](vuejs/core#14964)) ([e450973](vuejs/core@e450973))
* **runtime-core:** handle non-isomorphic block element update ([#15002](vuejs/core#15002)) ([932ddd0](vuejs/core@932ddd0)), closes [#6385](vuejs/core#6385)
* **runtime-core:** normalize function children for elements and Teleport ([#9108](vuejs/core#9108)) ([2f374cd](vuejs/core@2f374cd)), closes [#9107](vuejs/core#9107)
* **runtime-core:** pause tracking when invoking function refs ([#14985](vuejs/core#14985)) ([3ac052b](vuejs/core@3ac052b))
* **runtime-core:** preserve once event listener name ([#8341](vuejs/core#8341)) ([87b73b6](vuejs/core@87b73b6)), closes [#8342](vuejs/core#8342)
* **runtime-dom:** preserve option modifier event names ([#8338](vuejs/core#8338)) ([4b659e6](vuejs/core@4b659e6)), closes [#8334](vuejs/core#8334)
* **ssr:** dedupe inherited scope ids during vnode rendering ([#15005](vuejs/core#15005)) ([027da6b](vuejs/core@027da6b)), closes [#12159](vuejs/core#12159) [#12175](vuejs/core#12175)
* **ssr:** resolve nested async teleport content ([#9431](vuejs/core#9431)) ([31d0f23](vuejs/core@31d0f23)), closes [#6207](vuejs/core#6207)
* **teleport:** handle teleport unmount edge case ([#12705](vuejs/core#12705)) ([671997a](vuejs/core@671997a)), closes [#12702](vuejs/core#12702)
* **types:** support named tuple emits ([#12676](vuejs/core#12676)) ([232f402](vuejs/core@232f402)), closes [#12673](vuejs/core#12673)
* **types:** validate defineModel defaults ([#14968](vuejs/core#14968)) ([747f57e](vuejs/core@747f57e)), closes [#14966](vuejs/core#14966)

== [3.5.38](vuejs/core@v3.5.37...v3.5.38) (2026-06-11)

== [3.5.37](vuejs/core@v3.5.36...v3.5.37) (2026-06-11)

== [3.5.36](vuejs/core@v3.5.35...v3.5.36) (2026-06-11)


== Bug Fixes

* **compiler-core:** avoid crash on CDATA at the document root ([#14916](vuejs/core#14916)) ([0ea17e2](vuejs/core@0ea17e2))
* **compiler-core:** prefix dynamic keys on v-memo elements ([#14922](vuejs/core#14922)) ([68e978e](vuejs/core@68e978e)), closes [#14920](vuejs/core#14920)
* **compiler-sfc:** handle vue-ignore on leading intersection/union type ([#14950](vuejs/core#14950)) ([0dcd225](vuejs/core@0dcd225)), closes [#12254](vuejs/core#12254)
* **compiler-sfc:** respect var hoisting in props destructure ([48ad452](vuejs/core@48ad452))
* **reactivity:** preserve watch callback return value when wrapped for `once: true` ([#14902](vuejs/core#14902)) ([450a8a8](vuejs/core@450a8a8))
* **runtime-core:** add dev warning for silent catch in compat mode and fix test description typo ([#14891](vuejs/core#14891)) ([db3e117](vuejs/core@db3e117))
* **runtime-core:** force model update when reverted before sync ([#14897](vuejs/core#14897)) ([7f76378](vuejs/core@7f76378)), closes [#13524](vuejs/core#13524)
* **runtime-core:** skip async component callbacks after unmount ([#14911](vuejs/core#14911)) ([5300ead](vuejs/core@5300ead))
* **transition:** avoid move transition for hidden v-show group children ([#14895](vuejs/core#14895)) ([c11f6ee](vuejs/core@c11f6ee)), closes [#14894](vuejs/core#14894)
* **watch:** trigger immediate callback for empty sources ([#14914](vuejs/core#14914)) ([1f2ca7e](vuejs/core@1f2ca7e)), closes [#14898](vuejs/core#14898)

== [3.5.35](vuejs/core@v3.5.34...v3.5.35) (2026-05-27)


== Bug Fixes

* **compiler-core:** avoid double processing v-for keys with v-memo ([#14861](vuejs/core#14861)) ([34a0ded](vuejs/core@34a0ded)), closes [#14859](vuejs/core#14859)
* **compiler-sfc:** resolve top-level exports from files registered as global types ([#14805](vuejs/core#14805)) ([3d077f2](vuejs/core@3d077f2)), closes [nuxt/nuxt#33694](nuxt/nuxt#33694)
* **runtime-core:** avoid repeated hydration mismatch checks ([#14857](vuejs/core#14857)) ([170fc95](vuejs/core@170fc95)), closes [#14855](vuejs/core#14855)
* **runtime-core:** skip idle persisted transition hooks in keep-alive moves ([#14865](vuejs/core#14865)) ([80fc139](vuejs/core@80fc139)), closes [#14031](vuejs/core#14031)
* **server-renderer:** propagate sync errors from `ssrRenderSuspense` ([#14804](vuejs/core#14804)) ([4760997](vuejs/core@4760997)), closes [nuxt/nuxt#28162](nuxt/nuxt#28162)
* **teleport:** skip child unmount when pending mount discarded ([#14876](vuejs/core#14876)) ([#14877](vuejs/core#14877)) ([584beb1](vuejs/core@584beb1))


== Performance Improvements

* **reactivity:** skip type checks for cached proxies ([#14860](vuejs/core#14860)) ([5734fe9](vuejs/core@5734fe9))
* **runtime-dom:** optimize array event handler dispatch ([#14828](vuejs/core#14828)) ([bb18dc8](vuejs/core@bb18dc8))
* **server-renderer:** avoid materializing iterables in ssrRenderList ([#14821](vuejs/core#14821)) ([1b7a2cc](vuejs/core@1b7a2cc))

== [3.5.34](vuejs/core@v3.5.33...v3.5.34) (2026-05-06)


== Bug Fixes

* **compiler-sfc:** infer Vue ref wrapper types when source is unresolvable ([#14758](vuejs/core#14758)) ([7f46fd4](vuejs/core@7f46fd4)), closes [#14729](vuejs/core#14729)
* **compiler-sfc:** preserve hash hrefs on `<image>` elements ([#14756](vuejs/core#14756)) ([090b2e3](vuejs/core@090b2e3))
* **compiler-sfc:** resolve type re-exports inside declare global ([#14766](vuejs/core#14766)) ([acfffe3](vuejs/core@acfffe3))
* **reactivity:** prevent orphan effect when created in a stopped scope ([#14778](vuejs/core#14778)) ([c8e2d4a](vuejs/core@c8e2d4a)), closes [#14777](vuejs/core#14777)
* **runtime-core:** avoid symbol coercion during props validation ([#8539](vuejs/core#8539)) ([23d4fb5](vuejs/core@23d4fb5)), closes [#8487](vuejs/core#8487)
* **suspense:** avoid DOM leak with out-in transition in v-if fragment ([#14762](vuejs/core#14762)) ([9667e0d](vuejs/core@9667e0d)), closes [#14761](vuejs/core#14761)

== [3.5.33](vuejs/core@v3.5.32...v3.5.33) (2026-04-22)


== Bug Fixes

* **compiler-sfc:** handle nested :deep in selector pseudos ([#14725](vuejs/core#14725)) ([bb9d265](vuejs/core@bb9d265)), closes [#14724](vuejs/core#14724)
* **reactivity:** unlink effect scopes on out-of-order off ([#14734](vuejs/core#14734)) ([e7659be](vuejs/core@e7659be)), closes [#14733](vuejs/core#14733)
* **runtime-dom:** preserve textarea resize dimensions ([#14747](vuejs/core#14747)) ([11fb2fd](vuejs/core@11fb2fd)), closes [#14741](vuejs/core#14741)
* **teleport:** don't move teleport children if not mounted ([#14702](vuejs/core#14702)) ([6a61f44](vuejs/core@6a61f44)), closes [#14701](vuejs/core#14701)
* **transition:** preserve placeholder for conditional explicit default slots ([#14748](vuejs/core#14748)) ([45990ce](vuejs/core@45990ce)), closes [#14727](vuejs/core#14727)



== [3.5.32](vuejs/core@v3.5.31...v3.5.32) (2026-04-03)


== Bug Fixes

* **runtime-core:** prevent currentInstance leak into sibling render during async setup re-entry ([#14668](vuejs/core#14668)) ([f166353](vuejs/core@f166353)), closes [#14667](vuejs/core#14667)
* **teleport:** handle updates before deferred mount ([#14642](vuejs/core#14642)) ([32b44f1](vuejs/core@32b44f1)), closes [#14640](vuejs/core#14640)
* **types:** allow customRef to have different getter/setter types ([#14639](vuejs/core#14639)) ([e20ddb0](vuejs/core@e20ddb0))
* **types:** use private branding for shallowReactive ([#14641](vuejs/core#14641)) ([302c47a](vuejs/core@302c47a)), closes [#14638](vuejs/core#14638) [#14493](vuejs/core#14493)


== Reverts

* Revert "fix(server-renderer): cleanup component effect scopes after SSR render" (#14674) ([219d83b](vuejs/core@219d83b)), closes [#14674](vuejs/core#14674) [#14669](vuejs/core#14669)



== [3.5.31](vuejs/core@v3.5.30...v3.5.31) (2026-03-25)


== Bug Fixes

* **compiler-sfc:** allow Node.js subpath imports patterns in asset urls ([#13045](vuejs/core#13045)) ([95c3356](vuejs/core@95c3356)), closes [#9919](vuejs/core#9919)
* **compiler-sfc:** support template literal as defineModel name ([#14622](vuejs/core#14622)) ([bd7eef0](vuejs/core@bd7eef0)), closes [#14621](vuejs/core#14621)
* **reactivity:** normalize toRef property keys before dep lookup + improve types ([#14625](vuejs/core#14625)) ([1bb28d0](vuejs/core@1bb28d0)), closes [#12427](vuejs/core#12427) [#12431](vuejs/core#12431)
* **runtime-core:** invalidate detached v-for memo vnodes after unmount ([#14624](vuejs/core#14624)) ([560def4](vuejs/core@560def4)), closes [#12708](vuejs/core#12708) [#12710](vuejs/core#12710)
* **runtime-core:** preserve nullish event handlers in mergeProps ([#14550](vuejs/core#14550)) ([5725222](vuejs/core@5725222))
* **runtime-core:** prevent merging model listener when value is null or undefined ([#14629](vuejs/core#14629)) ([b39e032](vuejs/core@b39e032))
* **runtime-dom:** defer teleport mount/update until suspense resolves ([#8619](vuejs/core#8619)) ([88ed045](vuejs/core@88ed045)), closes [#8603](vuejs/core#8603)
* **runtime-dom:** handle activeElement check in Shadow DOM for v-model ([#14196](vuejs/core#14196)) ([959ded2](vuejs/core@959ded2))
* **server-renderer:** cleanup component effect scopes after SSR render ([#14548](vuejs/core#14548)) ([862f11e](vuejs/core@862f11e))
* **suspense:** avoid unmount activeBranch twice if wrapped in transition ([#9392](vuejs/core#9392)) ([908c6ad](vuejs/core@908c6ad)), closes [#7966](vuejs/core#7966)
* **suspense:** update suspense vnode's el during branch self-update ([#12922](vuejs/core#12922)) ([a2c1700](vuejs/core@a2c1700)), closes [#12920](vuejs/core#12920)
* **transition:** skip enter guard while hmr updating ([#14611](vuejs/core#14611)) ([be0a2f1](vuejs/core@be0a2f1)), closes [#14608](vuejs/core#14608)
* **types:** prevent shallowReactive marker from leaking into value unions ([#14493](vuejs/core#14493)) ([3b561db](vuejs/core@3b561db)), closes [#14490](vuejs/core#14490)



== [3.5.30](vuejs/core@v3.5.29...v3.5.30) (2026-03-09)


== Bug Fixes

* **compat:** add `entities` to @vue/compat deps to fix CJS edge cases ([#12514](vuejs/core#12514)) ([e725a67](vuejs/core@e725a67)), closes [#10609](vuejs/core#10609)
* **custom-element:** ensure child component styles are injected in correct order before parent styles ([#13374](vuejs/core#13374)) ([1398bf8](vuejs/core@1398bf8)), closes [#13029](vuejs/core#13029)
* **custom-element:** properly locate parent when slotted in shadow dom ([#12480](vuejs/core#12480)) ([f06c81a](vuejs/core@f06c81a)), closes [#12479](vuejs/core#12479)
* **custom-element:** should properly patch as props for vue custom elements ([#12409](vuejs/core#12409)) ([740983e](vuejs/core@740983e)), closes [#12408](vuejs/core#12408)
* **reactivity:** avoid duplicate raw/proxy entries in Set.add ([#14545](vuejs/core#14545)) ([d943612](vuejs/core@d943612))
* **reactivity:** fix reduce on reactive arrays to preserve reactivity ([#12737](vuejs/core#12737)) ([16ef165](vuejs/core@16ef165)), closes [#12735](vuejs/core#12735)
* **reactivity:** handle `Set` with initial reactive values edge case ([#12393](vuejs/core#12393)) ([5dc27ca](vuejs/core@5dc27ca)), closes [#8647](vuejs/core#8647)
* **runtime-core:** warn about negative number in v-for ([#12308](vuejs/core#12308)) ([9438cc5](vuejs/core@9438cc5))
* **ssr:** prevent watch from firing after async setup await ([#14547](vuejs/core#14547)) ([6cda71d](vuejs/core@6cda71d)), closes [#14546](vuejs/core#14546)
* **types:** make generics with runtime props in defineComponent work (fix [#11374](vuejs/core#11374)) ([#13119](vuejs/core#13119)) ([cea3cf7](vuejs/core@cea3cf7)), closes [#13763](vuejs/core#13763)
* **types:** narrow useAttrs class/style typing for TSX ([#14492](vuejs/core#14492)) ([bbb8977](vuejs/core@bbb8977)), closes [#14489](vuejs/core#14489)



== [3.5.29](vuejs/core@v3.5.28...v3.5.29) (2026-02-24)


== Bug Fixes

* **runtime-core:** prevent instance leak in withAsyncContext ([#14445](vuejs/core#14445)) ([702284f](vuejs/core@702284f)), closes [nuxt/nuxt#33644](nuxt/nuxt#33644)
* **server-renderer:** render className as escaped string ([#14469](vuejs/core#14469)) ([da6690c](vuejs/core@da6690c))
* **transition:** prevent enter if leave is in progress ([#14443](vuejs/core#14443)) ([df059f8](vuejs/core@df059f8)), closes [#12091](vuejs/core#12091) [#12133](vuejs/core#12133)



== [3.5.28](vuejs/core@v3.5.27...v3.5.28) (2026-02-09)


== Bug Fixes

* **transition:** avoid unexpected `cancelled` parameter in transition `done` callback ([#14391](vuejs/core#14391)) ([6798853](vuejs/core@6798853))
* **compiler-sfc:** add resolution trying for `.mts/.cts` files ([#14402](vuejs/core#14402)) ([c09d41f](vuejs/core@c09d41f)), closes [vuejs/router#2611](vuejs/router#2611)
* **compiler-sfc:** no params were generated when using withDefaults ([#12823](vuejs/core#12823)) ([b0a1f05](vuejs/core@b0a1f05)), closes [#12822](vuejs/core#12822)
* **reactivity:** add `__v_skip` flag to `EffectScope` to prevent reactive conversion ([#14359](vuejs/core#14359)) ([48b7552](vuejs/core@48b7552)), closes [#14357](vuejs/core#14357)
* **runtime-core:** avoid retaining el on cached text vnodes during static traversal ([#14419](vuejs/core#14419)) ([4ace79a](vuejs/core@4ace79a)), closes [#14134](vuejs/core#14134)
* **runtime-core:** prevent child component updates when style remains unchanged ([#12825](vuejs/core#12825)) ([57866b5](vuejs/core@57866b5)), closes [#12826](vuejs/core#12826)
* **runtime-core:** properly handle async component update before resolve ([#11619](vuejs/core#11619)) ([e71c26c](vuejs/core@e71c26c)), closes [#11617](vuejs/core#11617)
* **runtime-dom:** handle null/undefined handler in withModifiers ([#14362](vuejs/core#14362)) ([261de54](vuejs/core@261de54)), closes [#14361](vuejs/core#14361)
* **teleport:** properly handling disabled teleport target anchor ([#14417](vuejs/core#14417)) ([d7bcd85](vuejs/core@d7bcd85)), closes [#14412](vuejs/core#14412)
* **transition-group:** correct move translation under scale via element rect ([#14360](vuejs/core#14360)) ([0243a79](vuejs/core@0243a79)), closes [#14356](vuejs/core#14356)
* **useTemplateRef:** don't update setup ref for useTemplateRef key ([#12756](vuejs/core#12756)) ([fc40ca0](vuejs/core@fc40ca0)), closes [#12749](vuejs/core#12749)



== [3.5.27](vuejs/core@v3.5.26...v3.5.27) (2026-01-19)


== Bug Fixes

* **compile-sfc:** correctly handle variable shadowing in for loop for `defineProps` destructuring. ([#14296](vuejs/core#14296)) ([6a1bb50](vuejs/core@6a1bb50)), closes [#14294](vuejs/core#14294)
* **compiler-sfc:** handle indexed access types in declare global blocks ([#14260](vuejs/core#14260)) ([e4091fe](vuejs/core@e4091fe)), closes [#14236](vuejs/core#14236)
* **compiler-sfc:** use correct scope when resolving indexed access types from external files ([#14297](vuejs/core#14297)) ([f0f0a21](vuejs/core@f0f0a21)), closes [#14292](vuejs/core#14292)
* **reactivity:** collection iteration should inherit iterator instance methods ([#12644](vuejs/core#12644)) ([3c8b2fc](vuejs/core@3c8b2fc)), closes [#12615](vuejs/core#12615)
* **runtime-core:** skip patching reserved props for custom elements ([#14275](vuejs/core#14275)) ([19cc7e2](vuejs/core@19cc7e2)), closes [#14274](vuejs/core#14274)
* **server-renderer:** use ssrRenderClass helper for className attribute ([#14327](vuejs/core#14327)) ([a4708f3](vuejs/core@a4708f3))
* **ssr:** handle v-bind modifiers during render attrs ([#14263](vuejs/core#14263)) ([c2f5964](vuejs/core@c2f5964)), closes [#14262](vuejs/core#14262)



== [3.5.26](vuejs/core@v3.5.25...v3.5.26) (2025-12-18)


== Bug Fixes

* **compat:** fix compat handler of draggable ([#12445](vuejs/core#12445)) ([ed85953](vuejs/core@ed85953)), closes [#12444](vuejs/core#12444)
* **compat:** handle v-model deprecation warning with missing appContext ([#14203](vuejs/core#14203)) ([945a543](vuejs/core@945a543)), closes [#14202](vuejs/core#14202)
* **compiler-sfc:** demote const reactive bindings used in v-model ([#14214](vuejs/core#14214)) ([e24ff7d](vuejs/core@e24ff7d)), closes [#11265](vuejs/core#11265) [#11275](vuejs/core#11275)
* **compiler-ssr:** handle ssr attr fallthrough when preserve whitespace ([#12304](vuejs/core#12304)) ([4783118](vuejs/core@4783118)), closes [#8072](vuejs/core#8072)
* **hmr:** handle cached text node update ([#14134](vuejs/core#14134)) ([69ce3c7](vuejs/core@69ce3c7)), closes [#14127](vuejs/core#14127)
* **keep-alive:** use resolved component name for async components in cache pruning ([#14212](vuejs/core#14212)) ([dfe667c](vuejs/core@dfe667c)), closes [#14210](vuejs/core#14210)
* **runtime-core:** ensure correct anchor el for deeper unresolved async components ([#14182](vuejs/core#14182)) ([f5b3bf2](vuejs/core@f5b3bf2)), closes [#14173](vuejs/core#14173)
* **runtime-core:** handle patch stable fragment edge case ([#12411](vuejs/core#12411)) ([94aeb64](vuejs/core@94aeb64)), closes [#12410](vuejs/core#12410)
* **runtime-core:** pass component instance to flushPreFlushCbs on unmount ([#14221](vuejs/core#14221)) ([e857e12](vuejs/core@e857e12)), closes [#14215](vuejs/core#14215)


== Performance Improvements

* **compiler-core:** use binary-search to get line and column ([#14222](vuejs/core#14222)) ([1904053](vuejs/core@1904053))



== [3.5.25](vuejs/core@v3.5.24...v3.5.25) (2025-11-24)


== Bug Fixes

* **compiler:** share logic for comments and whitespace ([#13550](vuejs/core#13550)) ([2214f7a](vuejs/core@2214f7a))
* **provide:** warn when using `provide` after mounting ([#13954](vuejs/core#13954)) ([247b2c2](vuejs/core@247b2c2)), closes [#13921](vuejs/core#13921) [#13924](vuejs/core#13924)
* **reactivity:** correctly wrap iterated array items to preserve their readonly status ([#14120](vuejs/core#14120)) ([301020b](vuejs/core@301020b))
* **reactivity:** toRef edge cases for ref unwrapping ([#12420](vuejs/core#12420)) ([0d2357e](vuejs/core@0d2357e))
* **runtime-core:** keep options API typing intact when expose is used ([#14118](vuejs/core#14118)) ([8f82f23](vuejs/core@8f82f23)), closes [#14117](vuejs/core#14117) [vuejs/language-tools#5069](vuejs/language-tools#5069)
* **suspense:** defer clearing fallback vnode el in case it has dirs ([#14080](vuejs/core#14080)) ([c0f63dd](vuejs/core@c0f63dd)), closes [#14078](vuejs/core#14078)



== [3.5.24](vuejs/core@v3.5.23...v3.5.24) (2025-11-07)


== Reverts

* Revert "fix(compiler-core): correctly handle ts type assertions in expression…" (#14062) ([11ec51a](vuejs/core@11ec51a)), closes [#14062](vuejs/core#14062) [#14060](vuejs/core#14060)



== [3.5.23](vuejs/core@v3.5.22...v3.5.23) (2025-11-06)


== Bug Fixes

* **compiler-core:** correctly handle ts type assertions in expressions ([#13397](vuejs/core#13397)) ([e6544ac](vuejs/core@e6544ac)), closes [#13395](vuejs/core#13395)
* **compiler-core:** fix v-bind shorthand handling for in-DOM templates ([#13933](vuejs/core#13933)) ([b3cca26](vuejs/core@b3cca26)), closes [#13930](vuejs/core#13930)
* **compiler-sfc:** resolve numeric literals and template literals without expressions as static property key ([#13998](vuejs/core#13998)) ([75d44c7](vuejs/core@75d44c7))
* **compiler-ssr:** textarea with v-text directive SSR ([#13975](https://github.com/vuejs/core/issues/13975)) ([006a0c1](vuejs/core@006a0c1))
* **compiler:** using guard instead of non-nullish assertion ([#13982](https://github.com/vuejs/core/issues/13982)) ([dcc6f36](vuejs/core@dcc6f36))
* **custom-element:** batch custom element prop patching ([#13478](https://github.com/vuejs/core/issues/13478)) ([c13e674](vuejs/core@c13e674)), closes [#12619](https://github.com/vuejs/core/issues/12619)
* **custom-element:** optimize slot retrieval to avoid duplicates ([#13961](https://github.com/vuejs/core/issues/13961)) ([84ca349](vuejs/core@84ca349)), closes [#13955](https://github.com/vuejs/core/issues/13955)
* **hydration:** avoid mismatch during hydrate text with newlines in interpolation ([#9232](https://github.com/vuejs/core/issues/9232)) ([6cbdf78](vuejs/core@6cbdf78)), closes [#9229](https://github.com/vuejs/core/issues/9229)
* **runtime-core:** pass props and children to loadingComponent ([#13997](https://github.com/vuejs/core/issues/13997)) ([40c4b2a](vuejs/core@40c4b2a))
* **runtime-dom:** ensure iframe sandbox is handled as an attribute to prevent unintended behavior ([#13950](https://github.com/vuejs/core/issues/13950)) ([5689884](vuejs/core@5689884)), closes [#13946](https://github.com/vuejs/core/issues/13946)
* **suspense:** clear placeholder and fallback el after resolve to enable GC ([#13928](https://github.com/vuejs/core/issues/13928)) ([f411c66](vuejs/core@f411c66))
* **transition-group:** use offsetLeft and offsetTop instead of getBoundingClientRect  to avoid transform scale affect animation ([#6108](https://github.com/vuejs/core/issues/6108)) ([dc4dd59](vuejs/core@dc4dd59)), closes [#6105](https://github.com/vuejs/core/issues/6105)
* **v-model:** handle number modifier on change ([#13959](https://github.com/vuejs/core/issues/13959)) ([8fbe48f](vuejs/core@8fbe48f)), closes [#13958](https://github.com/vuejs/core/issues/13958)




Release notes: https://github.com/vuejs/core/blob/main/CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory leak in Vue

3 participants