# How can I quit from a Active Form

**URL:** <https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144>\
**Category:** Rasa Open Source\
**Created:** [January 8, 2019, 7:27pm UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144 "2019-01-08T19:27:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![kevinfaguiar](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/kevinfaguiar/32/1545_2.png) [@kevinfaguiar](https://forum.rasa.com/u/kevinfaguiar)\
**Post date:** [January 8, 2019, 7:27pm UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/1 "2019-01-08T19:27:36Z")

</div>

Hello everyone…

I am in doubt about how I can exit an active form using the user input (“fromText” method in slot type).

I tested the “/restart” command and saw that it takes precedence over all other methods, then closing the active form and clearing the slots.

This is exactly what I want, but the problem is that I would like to use another trigger word instead of “/restart”, such as “/cancel” or “/quit”.

Is there any way I can create custom actions that have a trigger that is a priority to all the others, in order to achieve this purpose, which is to close an active form from the user’s text input (using the “fromText” user text input method for the slot)?

---

<div class="post-metadata">

**Author:** ![Ghostvv](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/ghostvv/32/211_2.png) [@Ghostvv](https://forum.rasa.com/u/Ghostvv)\
**Post date:** [January 9, 2019, 9:59am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/2 "2019-01-09T09:59:35Z")

</div>

there is default action `action_deactivate_form` that if predicted (you need to have corresponding stories) deactivates current active form.

another way is in your custom validate method return `self._deactivate()` if certain intent

---

<div class="post-metadata">

**Author:** ![kevinfaguiar](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/kevinfaguiar/32/1545_2.png) [@kevinfaguiar](https://forum.rasa.com/u/kevinfaguiar)\
**Post date:** [January 9, 2019, 10:34am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/3 "2019-01-09T10:34:32Z")

</div>

> [@Ghostvv](#):
>
> self.\_deactivate()

Well, I tried returning self.\_deactivate() in my custom validation, and it deactivate but there is a problem: if there is a required field not filled yet in the form it will concatenate the self.\_deactivate() + set required\_slot action to the next required field. So I don’t like this approach since, lets imagine this scenario:

- I have a FormAction with 3 required fields:

- TICKET\_TYPE (using slot\_mapping = self.from\_text())
- TICKET\_DETAILS (using slot\_mapping = self.from\_text())
- TICKET\_QUANTITY (using slot\_mapping = self.from\_text())

So, when I enter in this Form it will ask for TICKET\_TYPE, which expect any text from the user.

Ok then, now let’s suppose, when the bot asks me about TICKET\_DETAILS (utter\_ask\_TICKET\_DETAILS) I want to cancel the form with “/cancel”. If I cancel the form using the command “/cancel” (catching this string in the custom validation method) and then return self.\_deactivate(), it appears to concatenate the form deactivation command + setting a required slot, like:

> [‘Form(None)’, ‘SlotSet(key: requested\_slot, value: None)’, ‘SlotSet(key: requested\_slot, value: TICKET\_DETAILS)’]

When it should be:

> [‘Form(None)’, ‘SlotSet(key: requested\_slot, value: None)’]

So, what is the problem with canceling from inside the custom validation method? Basically, when it appends the “SlotSet(key: requested\_slot, value: TICKET\_DETAILS)”, it will call utter\_ask\_TICKET\_DETAILS, which doesn’t make any sense in this context since the form is already canceled (and yet the bot will ask for the new field).

So the problem with this approach is the bot uttering ‘utter\_ask\_TICKET\_DETAILS’ even after deactivating the form, which doesn’t make sense since the user is already out of the form (now deactivated).

This scenario and behavior don’t occur, however, when typing “/restart” in the user input.

---

<div class="post-metadata">

**Author:** ![Ghostvv](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/ghostvv/32/211_2.png) [@Ghostvv](https://forum.rasa.com/u/Ghostvv)\
**Post date:** [January 9, 2019, 10:52am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/4 "2019-01-09T10:52:30Z")

</div>

I see your point, so `self._deactivate()` should be returned in `request_next_slot(...)` then, instead of asking the next question

---

<div class="post-metadata">

**Author:** ![kevinfaguiar](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/kevinfaguiar/32/1545_2.png) [@kevinfaguiar](https://forum.rasa.com/u/kevinfaguiar)\
**Post date:** [January 9, 2019, 11:22am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/5 "2019-01-09T11:22:14Z")

</div>

Okay, but I will need to do some validation, no?

Because if I haven’t canceled it should request the next slot and not deactivate the form…

I thought in the “run” function, check if there is the deactivate form command, and if it exists, do not concatenate the command to request the next slot command, like (check TODO on what I was planning to do):

> def run(self, dispatcher, tracker, domain):

> ```
> events = self._activate_if_required(tracker)
> events.extend(self._validate_if_required(dispatcher, tracker, domain))
> 
> temp_tracker = tracker.copy()
> for e in events:
> if e['event'] == 'slot':
> temp_tracker.slots[e["name"]] = e["value"]
> 
> next_slot_events = self.request_next_slot(dispatcher, temp_tracker,
> domain)
> #TODO: Develop an condition (if) that if the deactivate command combination exists ([‘Form(None)’, ‘SlotSet(key: requested_slot, value: None)’]) do not extend the events list with events.extend(next_slot_events)
> if next_slot_events is not None:
> events.extend(next_slot_events)
> else:
> events.extend(self.submit(dispatcher, temp_tracker, domain))
> events.extend(self._deactivate())
> 
> return events
> 
> ```

I’m not, however, very familiar with Python yet, and I do not know what would be the ideal and more performative way of doing this condition. It would be of great help if you could help me with the writing of this condition in the best practices.

Also, is there any way to dispatch an event? Like, from inside the custom validation method, dispatch some event which is immediately and synchronously executed and only after that return the events of the custom validation method?

---

<div class="post-metadata">

**Author:** ![Ghostvv](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/ghostvv/32/211_2.png) [@Ghostvv](https://forum.rasa.com/u/Ghostvv)\
**Post date:** [January 9, 2019, 11:52am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/6 "2019-01-09T11:52:10Z")

</div>

there is no the best way. You can do validation, as you do now, then add condition in `request_next_slot`, smth along the line:

```auto
def request_next_slot(self,
                      dispatcher, # type: CollectingDispatcher
                      tracker, # type: Tracker
                      domain # type: Dict[Text, Any]
                      ):
    # type: (...) -> Optional[List[Dict]]
    """Request the next slot and utter template if needed,
        else return None"""

    intent = tracker.latest_message.get("intent", {}).get("name")
    if intent == 'cancel':
        return self._deactivate()
    else:
        for slot in self.required_slots(tracker):
            if self._should_request_slot(tracker, slot):
                logger.debug("Request next slot '{}'".format(slot))
                dispatcher.utter_template("utter_ask_{}".format(slot),
                                          tracker,
                                          silent_fail=False,
                                          **tracker.slots)
                return [SlotSet(REQUESTED_SLOT, slot)]

        logger.debug("No slots left to request")
        return None

```

---

<div class="post-metadata">

**Author:** ![Ghostvv](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/ghostvv/32/211_2.png) [@Ghostvv](https://forum.rasa.com/u/Ghostvv)\
**Post date:** [January 9, 2019, 11:53am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/7 "2019-01-09T11:53:39Z")

</div>

`run` method of a custom action returns a list of event that are executed afterwards

---

<div class="post-metadata">

**Author:** ![kevinfaguiar](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/kevinfaguiar/32/1545_2.png) [@kevinfaguiar](https://forum.rasa.com/u/kevinfaguiar)\
**Post date:** [January 9, 2019, 12:30pm UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/8 "2019-01-09T12:30:18Z")

</div>

Yes, I tried along the lines of what I’ve written (with a custom `run` method) but it is executed afterward so it doesn’t serve for solving this scenario.

I’ve now rewritten the custom action using a custom ‘`request_next_slot`’ along the lines of what you have written and I consider this a satisfactory solution for my scenario.

Thank you so much for the help!

---

<div class="post-metadata">

**Author:** ![stephens](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/stephens/32/1632_2.png) [@stephens](https://forum.rasa.com/u/stephens)\
**Post date:** [March 8, 2019, 6:55pm UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/10 "2019-03-08T18:55:37Z")

</div>

If the user raises another intent in the middle of a form, I’d like to switch intents. Can this also be accomplished with this approach?

I’m getting the following error when I call `return self._deactivate()`

AttributeError: ‘CustomerForm’ object has no attribute ‘\_deactivate’

---

<div class="post-metadata">

**Author:** ![Ghostvv](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/ghostvv/32/211_2.png) [@Ghostvv](https://forum.rasa.com/u/Ghostvv)\
**Post date:** [March 11, 2019, 9:12am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/11 "2019-03-11T09:12:58Z")

</div>

What version of `rasa_core_sdk`, do you use? We rename it to `self.deactivate()` at newer versions

---

<div class="post-metadata">

**Author:** ![stephens](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/stephens/32/1632_2.png) [@stephens](https://forum.rasa.com/u/stephens)\
**Post date:** [March 11, 2019, 4:27pm UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/12 "2019-03-11T16:27:30Z")

</div>

I’m on v0.12.0

---

<div class="post-metadata">

**Author:** ![Ghostvv](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/ghostvv/32/211_2.png) [@Ghostvv](https://forum.rasa.com/u/Ghostvv)\
**Post date:** [March 11, 2019, 4:39pm UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/13 "2019-03-11T16:39:32Z")

</div>

I don’t remember exactly in which version we changed it, please try without `_`

---

<div class="post-metadata">

**Author:** ![seera](https://avatars.discourse-cdn.com/v4/letter/s/9fc348/32.png) [@seera](https://forum.rasa.com/u/seera)\
**Post date:** [September 25, 2020, 8:25am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/14 "2020-09-25T08:25:19Z")

</div>

Please provide full action code

---

<div class="post-metadata">

**Author:** ![seera](https://avatars.discourse-cdn.com/v4/letter/s/9fc348/32.png) [@seera](https://forum.rasa.com/u/seera)\
**Post date:** [September 29, 2020, 2:49pm UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/15 "2020-09-29T14:49:29Z")

</div>

NameError: name ‘logger’ is not defined

Im getting this error. when executing

---

<div class="post-metadata">

**Author:** ![Yash\_kals](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/yash_kals/32/17304_2.png) [@Yash\_kals](https://forum.rasa.com/u/Yash_kals)\
**Post date:** [October 8, 2020, 5:20am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/16 "2020-10-08T05:20:32Z")

</div>

from rasa\_sdk.forms import logger, REQUESTED\_SLOT

first of import logger bt this line after that execute action file…i hope your problem will be solved.

---

<div class="post-metadata">

**Author:** ![seera](https://avatars.discourse-cdn.com/v4/letter/s/9fc348/32.png) [@seera](https://forum.rasa.com/u/seera)\
**Post date:** [October 15, 2020, 11:30am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/17 "2020-10-15T11:30:53Z")

</div>

when I’m using the deactivation custom action in my scenario.

Example: I’m giving cancel as input to deactivate the form. At that moment, the slots has been validating and giving default fallback question like ‘enter valid input’ along with form deactivation action.

I don’t want the validation question while deactivating the form. How to do it…

---

<div class="post-metadata">

**Author:** ![Yash\_kals](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/yash_kals/32/17304_2.png) [@Yash\_kals](https://forum.rasa.com/u/Yash_kals)\
**Post date:** [October 15, 2020, 11:32am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/18 "2020-10-15T11:32:49Z")

</div>

which version of Rasa are you use?

---

<div class="post-metadata">

**Author:** ![seera](https://avatars.discourse-cdn.com/v4/letter/s/9fc348/32.png) [@seera](https://forum.rasa.com/u/seera)\
**Post date:** [October 15, 2020, 11:36am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/19 "2020-10-15T11:36:37Z")

</div>

I’m using Rasa 1.10.12

---

<div class="post-metadata">

**Author:** ![Yash\_kals](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.rasa.com/yash_kals/32/17304_2.png) [@Yash\_kals](https://forum.rasa.com/u/Yash_kals)\
**Post date:** [October 15, 2020, 11:37am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/20 "2020-10-15T11:37:55Z")

</div>

@seera Can you share your code?

---

<div class="post-metadata">

**Author:** ![seera](https://avatars.discourse-cdn.com/v4/letter/s/9fc348/32.png) [@seera](https://forum.rasa.com/u/seera)\
**Post date:** [October 15, 2020, 11:39am UTC](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144/22 "2020-10-15T11:39:02Z")

</div>

def request\_next\_slot(

```
    self,

    dispatcher,

    tracker,

    domain

    ):# type: (...) -> Optional[List[Dict]]

    

    "Request the next slot and utter template if needed, else return None"

    intent = tracker.latest_message.get("intent", {}).get("name")

    if intent == 'stop':

        dispatcher.utter_message(template="utter_restartflow")

        return self._deactivate()

    else:

        for slot in self.required_slots(tracker):

            if self._should_request_slot(tracker, slot):

                logger.debug("Request next slot '{}'".format(slot))

                dispatcher.utter_template("utter_ask_{}".format(slot),

                                          tracker,

                                          silent_fail=False,

                                          **tracker.slots)

                return [SlotSet(REQUESTED_SLOT, slot)]

        logger.debug("No slots left to request")

        return None
```

[Next page](https://forum.rasa.com/t/how-can-i-quit-from-a-active-form/4144.md?page=2)
