Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix(provide): warn when using provide after mounting #13954

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
skirtles-code wants to merge 1 commit into vuejs:main
base: main
Choose a base branch
Loading
from skirtles-code:provide-warning

Conversation

@skirtles-code
Copy link
Contributor

@skirtles-code skirtles-code commented Sep 30, 2025
edited by coderabbitai bot
Loading

Closes #13921.

Background

As far as I'm aware, provide is only intended to be used during the creation of a component. The provided values are expected to be locked in once the component renders. Any descendants shouldn't need to worry about timing, any provided values will be ready immediately and won't change. This is baked into the design of provide/inject.

I believe the original intention was for provide to only work directly inside setup (both the warning message and the documentation suggest this too). But, in practice, it doesn't check for that, it only checks for the availability of currentInstance. That is available in other places, such as inside lifecycle hooks.

As pointed out in #13921, calling provide inside a lifecycle hook does mostly work, but not completely. Some parts of the code appear to have been written under the assumption that the provided values are only set prior to mounting. In my opinion, this is a valid assumption and the only change that is required is to tighten up the warnings to avoid incorrect usage.

I've extended the warning to also check for currentInstance.isMounted. This will lead to a warning in cases like this:

onMounted(() => {
 provide('foo', 'bar')
})

Why isMounted?

I chose to use currentInstance.isMounted for my check because I think it reflects the underlying restriction. You could, for example, still use provide inside onBeforeMounted. I'm not sure why that would be useful, but so long as the component hasn't mounted yet I didn't see any reason to log a warning.

Impact on existing applications

This PR only adds extra warnings, it shouldn't change how provide behaves. If someone is using provide inside onMounted then it will still 'work' as it did previously, just with an extra warning. In that sense, it's relatively safe to merge and shouldn't impact production builds.

I've marked this change as a fix because I think it needs to be included in the changelog. There will likely be some people who encounter this warning after upgrading and it would be helpful for them to be able to find this PR.

I'm not sure what the use case for calling provide inside a lifecycle hook would be. It would still need to be called during the synchronous execution of the hook, so it isn't really suited to asynchronous tasks such as loading data. Perhaps there's a use case involving providing values that come from template refs?

In any case, if provide is being used inside onMounted then I believe the 'correct' way to handle that would be to provide a ref during setup instead, then update that ref from inside onMounted.

I'm not sure whether this would impact any libraries. I did have a quick look through VueUse. From what I could tell it doesn't use provide and inject much, so it shouldn't be a problem.

Tests

The existing warning message wasn't being tested. Most of the test cases I've added are testing the existing code on main, so even if the other changes in this PR aren't viable it may still be possible to merge some of those tests. Only the final test is actually testing my change to provide.

Summary by CodeRabbit

  • Bug Fixes

    • Improved development-time warnings for incorrect use of dependency injection APIs, including usage outside setup and after component mount.
    • Ensures warnings trigger reliably without affecting normal runtime behavior.
  • Tests

    • Added comprehensive test coverage for warning scenarios, including misuse in render functions and lifecycle hooks.

Copy link

coderabbitai bot commented Sep 30, 2025
edited
Loading

Walkthrough

Adds warning tests for misuse of provide/inject and updates provide() runtime guards to warn when called without a current instance or after mount. Control flow in apiInject.ts is adjusted to use early guards and proceed with provides updates only when a current instance exists.

Changes

Cohort / File(s) Summary
Runtime DI guard adjustments
packages/runtime-core/src/apiInject.ts
Updated provide() to guard and warn in DEV when there is no current instance or when called after mount; refactored control flow to early-guard and proceed only when currentInstance exists.
Tests for incorrect usage warnings
packages/runtime-core/__tests__/apiInject.spec.ts
Added a "warnings for incorrect usage" suite with tests ensuring warnings for using inject/provide outside setup, provide in render, and provide within onMounted; imported onMounted for tests.

Sequence Diagram(s)

sequenceDiagram
 autonumber
 actor Caller
 participant CompInstance as ComponentInstance
 participant Runtime as provide()
 participant DI as Provides Map
 Caller->>Runtime: provide(key, value)
 Runtime->>CompInstance: get currentInstance
 alt No currentInstance
 note over Runtime: __DEV__ warn: "provide() can only be used inside setup."
 Runtime-->>Caller: return (no mutation)
 else Has currentInstance
 alt Instance is mounted
 note over Runtime: __DEV__ warn: "provide() should not be called after mount."
 %% Proceed despite warning
 end
 Runtime->>DI: ensure current provides (possibly Object.create(parent))
 Runtime->>DI: set key = value
 Runtime-->>Caller: done
 end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I twitch my ears at warnings bright,
"Provide with care, and set up right!"
In burrows deep, the keys now flow,
From root to kits, the values go.
I thump—tests pass! My tail’s alight,
A carrot toast to guards in flight. 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The linked issue #13921 requests a functional fix to ensure that when provide is called during or after rendering, descendant components correctly inherit the updated values; however, this PR only adds warnings and tests without altering provide’s behavior or the inheritance mechanism, leaving the propagation bug unresolved. Implement the actual inheritance propagation fix by modifying provide to recreate or update the prototype chain for provides during post-render calls so that grandchildren receive the updated values, in addition to emitting warnings.
Out of Scope Changes Check ⚠️ Warning The PR introduces new tests and imports for warning scenarios such as using provide inside onMounted, in render functions, or with inject outside of setup, which do not relate to the linked issue’s goal of fixing dependency injection inheritance during post-render updates. These additions extend test coverage beyond the scope of correcting the inheritance bug described in #13921. Remove or relocate the unrelated warning tests into a separate PR focused on API usage linting and ensure this PR exclusively addresses the inheritance propagation bug to maintain clear scope alignment.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix(provide): warn when using provide after mounting" succinctly captures the core change of the pull request by indicating that a warning will now be emitted if provide is invoked post-mount, matching the primary modification in the code. It is concise, focused on the main behavior change, and avoids extraneous detail, making it clear to reviewers what the PR addresses.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a8aa0b and ad3cb91.

📒 Files selected for processing (2)
  • packages/runtime-core/__tests__/apiInject.spec.ts (2 hunks)
  • packages/runtime-core/src/apiInject.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/runtime-core/__tests__/apiInject.spec.ts (2)
packages/runtime-core/src/apiInject.ts (2)
  • inject (47-85)
  • provide (10-34)
packages/runtime-core/src/index.ts (4)
  • inject (61-61)
  • provide (61-61)
  • h (109-109)
  • onMounted (49-49)
packages/runtime-core/src/apiInject.ts (2)
packages/runtime-core/src/component.ts (1)
  • currentInstance (711-711)
packages/runtime-core/src/index.ts (1)
  • warn (133-133)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules
  • GitHub Check: Header rules
  • GitHub Check: Pages changed

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 102 kB 38.6 kB 34.8 kB
vue.global.prod.js 160 kB 58.7 kB 52.2 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.7 kB 18.3 kB 16.7 kB
createApp 54.7 kB 21.3 kB 19.5 kB
createSSRApp 58.9 kB 23 kB 21 kB
defineCustomElement 60 kB 23 kB 21 kB
overall 68.8 kB 26.5 kB 24.2 kB

Copy link

pkg-pr-new bot commented Sep 30, 2025

Open in StackBlitz

@vue/compiler-core
npm i https://pkg.pr.new/@vue/compiler-core@13954
@vue/compiler-dom
npm i https://pkg.pr.new/@vue/compiler-dom@13954
@vue/compiler-sfc
npm i https://pkg.pr.new/@vue/compiler-sfc@13954
@vue/compiler-ssr
npm i https://pkg.pr.new/@vue/compiler-ssr@13954
@vue/reactivity
npm i https://pkg.pr.new/@vue/reactivity@13954
@vue/runtime-core
npm i https://pkg.pr.new/@vue/runtime-core@13954
@vue/runtime-dom
npm i https://pkg.pr.new/@vue/runtime-dom@13954
@vue/server-renderer
npm i https://pkg.pr.new/@vue/server-renderer@13954
@vue/shared
npm i https://pkg.pr.new/@vue/shared@13954
vue
npm i https://pkg.pr.new/vue@13954
@vue/compat
npm i https://pkg.pr.new/@vue/compat@13954

commit: ad3cb91

@edison1105 edison1105 added ready to merge The PR is ready to be merged. 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels Oct 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. ready to merge The PR is ready to be merged.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Dependency Injection inheritance fails when provided after grandchildren are rendered.

AltStyle によって変換されたページ (->オリジナル) /