# Stop slot filling after 3 failed runs

**URL:** <https://forum.rasa.com/t/stop-slot-filling-after-3-failed-runs/20244>\
**Category:** Rasa Open Source\
**Created:** [October 23, 2019, 3:19pm UTC](https://forum.rasa.com/t/stop-slot-filling-after-3-failed-runs/20244 "2019-10-23T15:19:01Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chatbot\_Ra](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/chatbot_ra/32/2238_2.png) [@Chatbot\_Ra](https://forum.rasa.com/u/Chatbot_Ra)\
**Post date:** [October 23, 2019, 3:19pm UTC](https://forum.rasa.com/t/stop-slot-filling-after-3-failed-runs/20244/1 "2019-10-23T15:19:01Z")

</div>

Hi

**Introduction:**

I have a custom form which collects a few pieces of information from a user: name, birthday,…

Everything the user enters is validated by my class `FormValidatorDispatcher`. This works great. For example if the user writes `31.13.1999` (which is not a valid birthday!) in the slot, the validation will give an error message and will ask the user to repeat this step.

**Goal:**

Some user may have troubles to fill out the slots correctly. I want to stop the form after the user failed 3 times for one slot.

**My approach:**

This is my class which contains all slots that have to be filled by the user (`name`, `name_last` and `birthday`).

```auto
class AuthenticateForm(FormAction):

    """Example of a custom form action"""

    def name(self):
        ....
        return "authenticate_form"

    @staticmethod
    def required_slots(tracker):
        ....
        return ["name", "name_last", "birthday"]

    def submit(self, dispatcher, tracker, domain):
        ....
        return []

    def slot_mappings(self):
        ....

        return {
            "name": [self.from_entity(entity="name", not_intent=["chitchat"])],
            "name_last": [self.from_entity(entity="name_last", not_intent=["chitchat"])],
            "birthday": [self.from_entity(entity="birthday", not_intent=["chitchat"])]
        }

    def validate(self,
                 dispatcher: CollectingDispatcher,
                 tracker: Tracker,
                 domain: Dict[Text, Any]) -> List[Dict]:
        """Validate extracted requested slot
            else reject the execution of the form action
        """
        # extract other slots that were not requested
        # but set by corresponding entity
        slot_values = self.extract_other_slots(dispatcher, tracker, domain)

        # extract requested slot
        slot_to_fill = tracker.get_slot(REQUESTED_SLOT)
        if slot_to_fill:
            slot_values.update(self.extract_requested_slot(dispatcher,
                                                           tracker, domain))
            if not slot_values:
                # reject form action execution
                # if some slot was requested but nothing was extracted
                # it will allow other policies to predict another action
                raise ActionExecutionRejection(self.name(),
                                               "Failed to validate slot {0} "
                                               "with action {1}"
                                               "".format(slot_to_fill,
                                                         self.name()))
        # we'll check when validation failed in order
        # to add appropriate utterances

        for slot, value in slot_values.items():

            if slot == 'birthday':

                validator_birthday = FormValidatorDispatcher()
                if validator_birthday.is_valid_birthday(value, dispatcher, tracker):
                    date = dt.datetime.strptime(value, "%d.%m.%Y")
                    date_string = dt.date.strftime(date, "%d.%m.%Y")
                    slot_values[slot] = date_string
                else:
                    slot_values[slot] = None

          
            if slot == 'name':

                validator_name = FormValidatorDispatcher()
                if validator_name.is_valid_name(value, dispatcher, tracker):
                    slot_values[slot] = value
                else:
                    slot_values[slot] = None

            if slot == 'name_last':
                count = 0
                if count <= 2:
                    validator_name_last = FormValidatorDispatcher()
                    if validator_name_last.is_valid_name_last(value, dispatcher, tracker):
                        slot_values[slot] = value

                    else:
                        slot_values[slot] = None
                        count += 1

                else:
                    return self.deactivate() # deactivate form

          

        # validation succeed, set the slots values to the extracted values
        return [SlotSet(slot, value) for slot, value in slot_values.items()]

```

I started with the slot `name_last`. I used a counter variable that starts with 0 --\> `counter = 0`. Each time the validation of the slot returns `False` (meaning the slot value is not valid), I incease the counter variable by 1. After 3 fails I want the form to be deactivated.

**My problem:**

It does not work, because each time the slot\_value is set to `None` my count variable is set to 0 again. I do not know where to place `count = 0` to initialize the variable.

_How can I count how many times the user failed to enter the correct value?_

Hope you can help me!!!

---

<div class="post-metadata">

**Author:** ![fuih](https://avatars.discourse-cdn.com/v4/letter/f/d78d45/32.png) [@fuih](https://forum.rasa.com/u/fuih)\
**Post date:** [October 24, 2019, 2:48pm UTC](https://forum.rasa.com/t/stop-slot-filling-after-3-failed-runs/20244/2 "2019-10-24T14:48:33Z")

</div>

Can you set the count to a slot, then when you deactivate the form, you also reset the count to 0 ?
