Entity is extracted with high confidence but throws "Failed to extract slot {slot_name} with action {form_name}" error

Hey. This is my first Rasa project and now I am stuck here for a week. Please respond ASAP if possible. I’m going behind my deadline already because of this :frowning:

I have a Form Action which has to fill 2 kind of slots:

  1. distance - this should be extracted either by Duckling “distance” entity, or Duckling “number” entity (it depends on the user response: “22 km” or just “22”)
  2. score - this is just a number in a defined range and should be extracted by Duckling “number” entity

I have gone through almost everything this week: your example formbot, your source cods etc and everything available in GitHub or forum.

So far, I came to a conclusion that I need to have 2 kind of entities: distance and number with the same names as Duckling entities. And I have to keep 2 slots: distance_slot and score correspondingly.

That’s why my slot_mapping looks like this:

    def slot_mapping(self,tracker):

        return {
             "distance_slot": [self.from_entity(entity="distance", intent=["inform"]),
                          self.from_entity(entity="number", intent=["inform"])
                          ],
            "score": self.from_entity(entity="number", intent=["inform"])
        }

So I train and run it in shell debug mode. The problem is the following: I see that it extracts distance when I write for example “30 miles” as “distance” entity with very high confidence and number entity when I just write “30” again with high confidence. But, It keeps throwing "Failed to extract slot distance_slot with action main_form" error.

What is wrong here, really?


Here is my code:

domain.yml

intents:
- mock:
    use_entities: []
- inform
- greet
entities:
- distance
- number
slots:
  distance_slot:
    type: unfeaturized
    auto_fill: false
  score:
    type: unfeaturized
    auto_fill: false
templates:
  utter_ask_distance_slot:
  - text: "Please provide distance"
  utter_ask_score:
  - text: 'Please provide score'
  utter_submit:
  - text: All done!
  utter_slots_values:
  - text: "OK. \n - distance: {distance_slot}\n - score: {score}"
  utter_wrong_distance:
  - text: wrong distance
  utter_wrong_score:
  - text: wrong score
  utter_greet:
  - text: Hello!
  utter_default:
  - text: sorry, I didn't understand you, please try input something else
actions:
- utter_slots_values
- utter_greet
forms:
- main_form

actions.py

from rasa_sdk.forms import FormAction

class MainForm(FormAction):

    def name(self):
        return "main_form"

    @staticmethod
    def required_slots(tracker):
        return ["distance_slot", "score"]

    def slot_mapping(self, tracker):

        return {
            "distance_slot": [
                self.from_entity(entity="distance", intent="inform"),
                self.from_entity(entity="number", intent="inform")
            ],
            "score": self.from_entity(entity="number", intent="inform")
        }

    @staticmethod
    def is_int(string):
        """Check if a string is an integer"""
        try:
            int(string)
            return True
        except ValueError:
            return False

    def validate_distance_slot(
            self,
            value,
            dispatcher,
            tracker,
            domain
    ):
        if self.is_int(value) and 1 <= int(value) <= 200:
            return {"distance_slot": value}
        else:
            dispatcher.utter_template("utter_wrong_distance", tracker)
            return {"distance_slot": None}

    def validate_score(
            self,
            value,
            dispatcher,
            tracker,
            domain,
    ):
        if self.is_int(value) and 100 < int(value) < 2000:
            return {"score": value}
        else:
            dispatcher.utter_template("utter_wrong_score", tracker)
            return {"score": None}

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

config.yml

language: en

pipeline:
  - name: WhitespaceTokenizer
  - name: EntitySynonymMapper
  - name: CountVectorsFeaturizer
    token_pattern: (?u)\b\w+\b
  - name: EmbeddingIntentClassifier
  - name: DucklingHTTPExtractor
    url: http://localhost:8000
    dimensions:
      - number
      - distance

policies:
  - name: FallbackPolicy
  - name: MemoizationPolicy
  - name: FormPolicy
  - name: MappingPolicy

nlu.md (inform intent only)

## intent:inform
- my score is [750](number)
- score [650](number)
- [30 km](distance)  is good
- just [50 kilometers](distance) 
- [60 km](distance) 
- up to [70 km](distance) 
- [ten kilometers](distance) 
- [eleven km](distance) 
- my  score is just [650](number)
- [750](number)
- [680](number)
- [45](number)
- [55](number)
- [35](number)
- [40](number)
- [700](number)
- [600](number)
- just [40 miles](distance) 
- my  score is [700](number)
- my score is [750](number)
- just [40 km](distance) 
- my score is [750](number)
- my score is [750](number)

what are the logs from your action server

Here it is

could you please run it in debug mode

in the log, slot mapping is different from the one in the code

I see. But don’t understand why.

I don’t even have an entity named “distance_slot” which is mentioned in action server logs. Do you have any idea?

did you restart a server after changing the code?

Sure. I restarted it.

I just thought maybe there are inconveniences with name “distance_slot” but changing it didn’t help. I still get the same error.

You didn’t actually override slot_mappings:

In your custom code it is named differently, therefore it is trying to extract slot from the entity with the same name (default behavior)

:man_facepalming: just a typo ruined my last few days.

Thanks a lot, Vladimir! Sorry for taking your time just because of a typo.