Common error ‘Microsoft.Bot.Builder.Internals.Fibers.InvalidNeedException’


Bot Error

Using the Microsoft Bot Framework streamlines the development of Bots and makes the process of integrating a Bot with common platforms\channels easier.
Here is a good example of building a Bot, hosting it on a Xamarin phone App and making use of the Microsoft cognitive API LUIS to provide a more human experience.
One of the common issues developers run into, is getting the following error from the Bot:
Exception thrown: ‘Microsoft.Bot.Builder.Internals.Fibers.InvalidNeedException’ in mscorlib.dll
invalid need: expected Wait, have Done
Exception type: “Microsoft.Bot.Builder.Internals.Fibers.InvalidNeedException”

This error can be annoying because it doesn’t go away even if you restarted or redeployed your Bot Web API project.
Before we talk about how you can fix it, I would like to briefly mention how to avoid it.

Avoiding the error

Whenever you open a conversation and program your Bot to send response messages like this for example:

 await context.PostAsync("I'm sorry I don't understand. Can you clarify please?");

You need to make sure you also call wait or done after words like this:

 context.Done(true);

Fixing the error

Because your conversation hasn’t been ended (sort of in a hang state) it cannot receive more messages (activities) from the user. So in order to resolve this you need to access the conversation state store and flush it. The way I have achieved this as follows:

 StateClient stateClient = activity.GetStateClient();
 await stateClient.BotState.DeleteStateForUserAsync(activity.ChannelId, activity.From.Id);

As you see above, this will result into deleting the conversation history so be aware of that.
That code I listed above can be placed inside your Post method implementation part of the Message controller. We can provide a better visibility to the user and handle the error as follows:

 case ActivityTypes.Message:
 try
 {
 await Conversation.SendAsync(activity, () => new ShoppingDialog());
 }
 catch(Exception Ex)
 {
 if (Ex.GetType() == typeof(InvalidNeedException))
 {
 ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
 Activity reply = activity.CreateReply("Sorry, I'm having some difficulties here. I have to reboot myself. Lets start over.");
 await connector.Conversations.ReplyToActivityAsync(reply);
 StateClient stateClient = activity.GetStateClient();
 await stateClient.BotState.DeleteStateForUserAsync(activity.ChannelId, activity.From.Id);
 }
 }
 break;

Additional resources

Comments (0)

Skip to main content