Skip to content

(runtime-core): Runtime error when mistakenly converting symbols to a string during props validation #8487

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
mattersj opened this issue Jun 2, 2023 · 5 comments · May be fixed by #8539 or #7809
Open
Labels
has PR A pull request has already been submitted to solve the issue 🔩 p2-edge-case

Comments

@mattersj
Copy link
Contributor

mattersj commented Jun 2, 2023

Vue version

3.3.4

Link to minimal reproduction

https://play.vuejs.org/#eNqFjsEKgzAQRH9lyaUWiqFXiULxBwSvuViNNWCSJVkLRfz3Rm2hhUJvO7uzb2ZmF8T0PimWMRFar5EgKJqwkFYbdJ6gdAah987AIeWrWO0HaaVtnQ3R/jBXN0IO9TYkR2kF31EREgUpg2NDKioAMZyLqvHKkuBx3FZbQkYqUC7ZjpMMeDwK/vHMTuwd/6Ntp3ptVeUdhmSGFZZBTV7bGyz/K5WDHrtXo+/Q5QneXWVa

Steps to reproduce

Steps to reproduce the bug from scratch (repro already has this covered):

  1. Pass a symbol as a prop value to a component that expects another type.
  2. Observe a runtime error since symbols can't be converted to string or number.

What is expected?

A classic warning about type mismatch, e.g. Invalid prop: type check failed for prop "propName". Expected String, got Symbol

What is actually happening?

A runtime error because getInvalidTypeMessage function is trying to convert the symbol to a string/number.

System Info

System:
    OS: macOS 12.4
    CPU: (10) arm64 Apple M1 Pro
    Memory: 92.69 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node
    npm: 8.19.2 - ~/.nvm/versions/node/v18.12.1/bin/npm
  Browsers:
    Chrome: 114.0.5735.90
    Firefox: 112.0.2
    Safari: 15.5
  npmPackages:
    vue: ^3.3.4 => 3.3.4

Any additional comments?

The fix could be pretty straightforward: check if we have a symbol in styleValue function and do not convert a value to anything else since it won't be useful anyway.

I'm going to submit a PR that fixes this issue.

@sxzz sxzz added has PR A pull request has already been submitted to solve the issue 🔩 p2-edge-case labels Jun 11, 2023
@dodgex
Copy link

dodgex commented Jul 12, 2023

I was about to create an issue for this, but last minute i found this one. From my testing the bug was introduced in 3.3.0-alpha.13, alpha 12 was still working.

would love to see this fixed :)

@mattersj
Copy link
Contributor Author

@dodgex I believe that this bug has been around for a while since the affected part of the code hasn't been changed in ~4 years. It seems you can reproduce it on almost every 3.x version, not only 3.3.x.

@dodgex
Copy link

dodgex commented Jul 12, 2023

@mattersj my project is on 3.2.45 and i have multiple components using symbols (InjectionKey to be accurate) as props. and with 3.3.4 i got this issue.

I tested alpha.1, .6, .12 and .13 aswell as .beta1 and the 3.3.0 release. with versions <= alpha.12 it worked; with >= alpha.13 I got the Cannot convert a Symbol value to a string runtime error.

I even had a project prepared to reproduce my issue working with .12 and failing with .13+, but then i found this issue and deleted it... if necessary i could recreate it later or tomorrow.

@mattersj
Copy link
Contributor Author

mattersj commented Jul 12, 2023

@dodgex I think you're talking about slightly different issue here:

Since 3.3 (probably, specifically alpha.13 as you mentioned) Vue has changed the way types get resolved and this is also true for InjectionKey. That means that previously (<= alpha.12), InjectionKey wasn't resolved properly and the type was null so you could pass basically anything and it worked fine, but from alpha.13 things changed and InjectionKey is now resolved to an Object constructor instead of a Symbol one, so when you pass a symbol and Vue expects an object, you hit the error we're talking about in this subject, because Vue tries to convert this symbol to a string.

That way, you just encountered another bug related to a type resolving, so feel free to open a new issue if one is not created yet.

P.S. as a temporary solution you can replace InjectionKey with just Symbol and it should work fine.

@dodgex
Copy link

dodgex commented Jul 14, 2023

I tried to recreate the repro for a new issue as you suggested but now it seems to work in a blank vue project. No Idea what i did diffrent 2 days ago when testing it.

But what I found is that it somehow relates my tsconfig.json. When using my tsconfig in the blank project it fails; with the tsconfig(s) setup generated by npm init vue@latest it works. Sadly using the generated files breaks the whole project and sadly I currently do not have the time to fix the whole project (have to replace all import statements that import types to import type; and what ever comes after this).

For now i might have to abort and delay the upgrade to vue3.3; but in case you can see an issue and have a suggestion what could be causing this, i leave my tsconfig below.

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "lib": [
      "esnext",
      "dom"
    ],
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ]
}

Thanks and sorry for hijacking this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has PR A pull request has already been submitted to solve the issue 🔩 p2-edge-case
Projects
None yet
3 participants