Vee-validate: Validating a non-existent field: "result". Use "attach()" first.

Created on 27 Jan 2019  ·  26Comments  ·  Source: logaretm/vee-validate

Versions

  • vee-validate: 2.1.6
  • vue: 2.5.2

Describe the bug
So I am getting this error on my system "Uncaught (in promise) Error: [vee-validate] Validating a non-existent field: "result". Use "attach()" first." I don't know why I get this error. Also I am not getting this error for every field I use this.$validator.validate() on but only in the last step

To reproduce
Created this fiddle
https://jsfiddle.net/f1uk3r/bnrpdg01/1/

Expected behavior
The error should not come and it should log "passed when clicked submit."

🐛 bug

Most helpful comment

Use 2.2.6 and got this error message: [vee-validate] Validating a non-existent field: "#5". Use "attach()" first. Components inputs get destroyed then auto validate - non existing in DOM as result. But how to avoid this?

All 26 comments

When building a multi-step form, be mindful that Vue re-uses inputs to be more efficient, what happened here is that your inputs got re-used from the previous step causing the validation to break since the new fields (location, address) were never mounted in the DOM. Adding key attribute to your inputs ensure each input is unique and should not be re-used in future steps.

https://jsfiddle.net/f1uk3r/bnrpdg01/1/

You can read more about this behavior in Vue.js docs

The actual bug here is The error message you received, it tries to reference a variable called name which can be set by any hoisted identifier which happens to be result in your case. This is fixed and will land in the next release.

Thank you, that solved my problem.

Use 2.2.6 and got this error message: [vee-validate] Validating a non-existent field: "#5". Use "attach()" first. Components inputs get destroyed then auto validate - non existing in DOM as result. But how to avoid this?

@emprove I had this same error when I was migrating from version 2.1.7 to 2.2.7. I forgot handle promise from $validator.reset() in modal submit function.

I found another solution:
beforeDestroy() { this.$validator.pause() },
The second approach is to make fields .persist: https://baianat.github.io/vee-validate/api/directive.html#directive-modifiers.
But it still need additional code to cover this issue. I think this topic need some attention.

I'm still having this issue in 2.2.8.

same here even with key

add :key on this componet that have v-if not on input

for example:

<div v-if="condition" :key="uuid">
<input v-validate="required" v-model="model" />
</div>

this work for me.

I found a cause and solution to this. See https://github.com/baianat/vee-validate/issues/2109

I am having the same issue. I have component rendered with v-if, and in a template slot, i have an input field with a v-validate.

Depending on the selection of a drop down, another field is dynamically switched from being a dropdown to a text field.

If I fill out the form manually, everything works fine. If I use the browser's autocomplete, the one dropdown that triggers the other dropdown or text field, is auto-filled, and I get the error mentioned in the title. I have put unique key attributes on both the dropdown and the text field, but still this occurs.

add :key on this componet that have v-if not on input

for example:

<div v-if="condition" :key="uuid">
<input v-validate="required" v-model="model" />
</div>

this work for me.

This did't work for me.

Adding :key="..." did not help.
This worked for me:
<div v-show="condition" ... >
instead of:
<div v-if="condition"... >

In my case I had a block of code rendered with v-if and inside of it I hade the input field with validation. This error showed up when I was setting the value of the input. As @jsodeman said in #2109, $nextTick helped me to solve this like this:

this.editForm = true;  //show the block with inputs
this.$nextTick(() => {
   // here set the value of inputs
})

It was not obvious for me but it s describe in the official vee validate documentation.
You can read it at https://baianat.github.io/vee-validate/guide/conditional-and-looping-inputs.html#validating-dynamically-displayed-inputs

I found another solution:
beforeDestroy() { this.$validator.pause() },
The second approach is to make fields .persist: https://baianat.github.io/vee-validate/api/directive.html#directive-modifiers.
But it still need additional code to cover this issue. I think this topic need some attention.

thanks @emprove
v-validate.persist="'required'" works for me

but not all time as i tried @kkojot suggestion and its also works for me

Adding :key="..." did not help.
This worked for me:
<div v-show="condition" ... >
instead of:
<div v-if="condition"... >

Thank you, it works for me!
In my case I have only 2 input fields and v-show never unmount them from DOM

Don't know why it closed, the bug still exists...

Yep, I've hit a wall trying to solve this one too. Has appeared in the last few days without us touching the part of our app that's handling forms. Very strange.

• Adding key doesn't help
• Adding .persist doesn't help
v-show instead of v-if fixed one instance we faced, but not the other main one we've found so far (it has to be a v-if)

My use case is slightly more complex — form fields that are using a slot that is inside of a v-if: Update: seeing this in a bunch of places throughout our app, not just in v-if + slots. Fields inside v-if seems consistently a problem

Updated a bunch of things, still seeing the problem

node v11.10.0
npm 6.10.3

vue 2.6.10
vee-validate 2.2.14

After some investigation browsing through a number of (unresolved yet closed) issues reporting this error (#2113, #2117, #2077 seems suspiciously similar), it seems that the maintainer isn't addressing this bug, instead is closing the issues and telling people to use the ValidationProvider component.

The directive timing issues is hard to pinpoint and fix completely. I suggest moving to ValidationProvider component as it is more robust and doesn't have the common issues of a directive.

The directive will be deprecated in v3

If that's the approach, fine, but it would perhaps be a good idea to get the docs updated to reflect that using the directive is in many cases (v-if to show fields is a very common use case) going to be unreliable, and no longer really receiving bug fixes. There is no visibility in the directive documentation over this currently — I'd suggest adding a note about the problems and note that it will be depreciated in v3.

@tbredin did you look at https://github.com/baianat/vee-validate/issues/2109 ? It might be that you're accidentally firing the validation after a field has been hidden.

I was also experiencing the same bug as mentioned by @emprove.
What I found was that the error was occurring when I was calling a function which ran the validator on blur @blur="validateEmail(index)", but I also had data-vv-validate-on="blur", which seemed to be causing a conflict.
Removing the data-vv-validate-on="blur" fixed the issue for me and now I am just calling the validator in the validateEmail(index) function.
This may not fix the issue for everyone but hopefully will be of use to somebody.

The $nextTick solution doesn't work for me.

Here is my exact flow and reasoning why this error was happening intermittently for me.

I had a login form, username and password with vee-validate attaching some validators to the fields (min-length etc etc). When the login button is clicked, I had a method defined that called this.$validators.validate which is an async call. It its then block we had a call to our vuex store to perform the login process then returned asynchronously which then changed the route to let the user in

The issue arose when the debounced internal vee-validate validators ran AFTER my vuex store performed the login action and changed the route, destroying the login page and destroying the inputs.

To solve this I used, as suggested above, this.$validator.pause() which disabled the vee-validate validators.

this.$validator.pause()
this.form = getDefaultValues()
this.$nextTick(() => {
this.$validator.reset()
this.$validator.resume()
})
may be someone can help

Adding :key="..." did not help.
This worked for me:
<div v-show="condition" ... >
instead of:
<div v-if="condition"... >

Thank you, it works for me!
In my case I have only 2 input fields and v-show never unmount them from DOM

This worked for me together with:

this.$validator.pause()
this.$nextTick(() => {
//do your thing
this.$validator.resume()
})

Was this page helpful?
0 / 5 - 0 ratings