Skip to content

Conversation

@ZKunZhang
Copy link

@ZKunZhang ZKunZhang commented Oct 31, 2025

Problem Description

  • When uncommenting <test-comp :modelValue="{ type: 'js' }" />, the app throws "Right-hand side of 'instanceof' is not an object" during hot-reload/render in development mode
  • The error occurs in the dev-only props type assertion path before the child component instance exists, so the parent onErrorCaptured cannot intercept it

Root Cause

  • assertType uses value instanceof type even when type is not a constructor/function (e.g., user mistakenly declares type: 'object', type: 'Object', or nested { type: String })
  • This causes a raw TypeError which bypasses Vue's error boundary

Change Summary

File: packages/runtime-core/src/componentProps.ts

  • Only execute instanceof checks when type is a function/constructor:
    // Before
    value instanceof (type as PropConstructor)
    
    // After
    isFunction(type) && value instanceof (type as PropConstructor)
  • Applied in both the "primitive wrapper objects" branch and the final fallback branch
  • Preserve existing dev warnings (warn(getInvalidTypeMessage(...))); do not crash

Behavior After Change

Development Environment

  • Invalid prop types produce an "Invalid prop" warning instead of throwing a TypeError
  • If a child later throws during render/effects, the parent onErrorCaptured can capture it (and apps can suppress overlays)

Production Environment

  • No change (prop type assertions are skipped in production)

Reproduction (Pre-fix)

  1. Parent template includes <test-comp :modelValue="{ type: 'js' }" />
  2. test-comp incorrectly declares modelValue prop type (e.g., type: 'object' or type: { type: String })
  3. Hot update or initial render throws "Right-hand side of 'instanceof' is not an object"; onErrorCaptured does not run

Validation

With the fix:

  • Uncommenting the usage no longer crashes; the page renders
  • Dev console shows a prop type warning (expected)
  • Any other runtime errors from test-comp are captured by the parent onErrorCaptured and no red overlay appears if handled

Scope and Risk

  • Scope: Dev-only prop type validation in runtime-core
  • Risk: Low; only adds an isFunction guard around instanceof
  • Performance: Negligible change

Related

Notes for App Authors

While the runtime now guards against crashes, component props should still be declared with valid constructors/PropType, e.g.:

type: Object as PropType<{ type: string }>

with an optional validator.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed component property validation to prevent runtime errors that could occur when invalid prop type definitions are used. The validation system now safely handles edge cases and non-standard configurations without crashing, enhancing application stability and preventing potential crashes during component initialization.

@coderabbitai
Copy link

coderabbitai bot commented Oct 31, 2025

Walkthrough

The code modifies the prop type assertion logic to guard instanceof checks with a function type check. Previously, when invalid prop type definitions were provided (non-function values), the code would attempt instanceof operations and throw runtime errors. Now it only performs instanceof when the type is a function/constructor, preventing "Right-hand side of 'instanceof' is not an object" errors.

Changes

Cohort / File(s) Change Summary
Prop type validation guard
packages/runtime-core/src/componentProps.ts
Added function type check before instanceof operations in assertType to prevent runtime errors when non-function values are passed as prop types

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

  • Key area: Verify the guarded instanceof check correctly handles all valid and invalid prop type scenarios
  • Confirm the fix resolves the reported issue without breaking legitimate type validation

Suggested labels

ready to merge, :hammer: p3-minor-bug

Suggested reviewers

  • edison1105

Poem

A rabbit hops through prop validation land,
Where instanceof once fell on faulty sand,
With careful guards, we dodge the runtime trap,
Now type checks dance without a mishap! 🐰✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "fix(runtime-core): guard prop validator against invalid types to avoid instanceof crash (fix #14041)" directly and clearly summarizes the main change in the pull request. It is specific, mentioning the module (runtime-core), the problem being fixed (guarding prop validator against invalid types), and the specific error being addressed (instanceof crash), while also referencing the linked issue. The title is concise and provides sufficient context for a developer scanning commit history to understand the primary objective of the change.
Linked Issues Check ✅ Passed The PR changes directly address all primary coding objectives from linked issue #14041. The modifications guard instanceof checks with function type verification in componentProps.ts, which prevents the TypeError when prop types are not constructors or functions. This aligns with the objective to prevent the "Right-hand side of 'instanceof' is not an object" error, allow the dev validation to emit warnings instead of crashing, and enable parent onErrorCaptured hooks to function correctly. The changes are applied in both the primitive wrapper-objects branch and the final fallback branch as described in the PR objectives, fulfilling the core requirements of issue #14041.
Out of Scope Changes Check ✅ Passed The changes in this PR are narrowly scoped to the specific problem described in linked issue #14041. All modifications are contained within packages/runtime-core/src/componentProps.ts in the assertType function, and consist solely of guarding existing instanceof checks with function type verification. There are no unrelated changes, refactorings, or modifications to other areas of the codebase that would fall outside the stated objectives of fixing the instanceof crash caused by invalid prop types.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • 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 45547e6 and 5586cda.

📒 Files selected for processing (1)
  • packages/runtime-core/src/componentProps.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/runtime-core/src/componentProps.ts (1)
packages/shared/src/general.ts (3)
  • isFunction (49-50)
  • isObject (53-54)
  • isArray (39-39)
⏰ 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
🔇 Additional comments (2)
packages/runtime-core/src/componentProps.ts (2)

740-742: LGTM! The guard prevents TypeError on invalid prop types.

The isFunction(type) check correctly prevents instanceof from throwing when type is not a constructor (e.g., string 'object' or plain object {}). This ensures invalid prop type definitions now emit dev warnings instead of crashing.


749-752: LGTM! The fallback guard is consistent with the primitive wrapper guard.

The isFunction(type) check prevents runtime errors when invalid custom types are provided. This is consistent with the guard on line 742 and ensures the entire assertType function is protected against non-constructor type definitions.


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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

onErrorCaptured hook fails to capture instanceof error from child component

1 participant