Botbuilder-dotnet: Cosmos DB Throws "Unable to cast object of type 'System.Int64' to type 'System.Int32'" when Calling ContinueDialogAsync

Created on 3 May 2019  路  9Comments  路  Source: microsoft/botbuilder-dotnet

Github issues should be used for bugs and feature requests. Use Stack Overflow for general "how-to" questions.

Version

Microsoft.Bot.Builder v4.4.0

Describe the bug

When executing line

await dialogContext.ContinueDialogAsync(cancellationToken)

System.InvalidCastException is thrown with details "Unable to cast object of type 'System.Int64' to type 'System.Int32'"

To Reproduce

Steps to reproduce the behavior:
Using CosmosDB storage
Execute the first message, works fine
Upon the second message, calling ContinueDialogAsync(...) fails

Expected behavior

Give a clear and concise description of what you expected to happen.

Screenshots

If applicable, add screenshots to help explain your problem.

Additional context

Using MemoryStorage does not have this problem
Works fine in version 4.3.0

[bug]

4.4 P0 bug

All 9 comments

@NiteLordz - Can you provide the code for the dialog you're running?

@NiteLordz, can you provide the full Exception stack? I would love to see the stack trace.

Also, if you can provide code that replicates the issue, we can quickly track it down.

Stack Trace:

TestCosmosBot.TestCosmosBotBot:Error: Exception caught : System.InvalidCastException: Unable to cast object of type 'System.Int64' to type 'System.Int32'.
   at Microsoft.Bot.Builder.Dialogs.Prompt`1.ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken)
   at Microsoft.Bot.Builder.Dialogs.DialogContext.ContinueDialogAsync(CancellationToken cancellationToken) in d:\a\1\s\libraries\Microsoft.Bot.Builder.Dialogs\DialogContext.cs:line 160
   at Microsoft.Bot.Builder.Dialogs.ComponentDialog.ContinueDialogAsync(DialogContext outerDc, CancellationToken cancellationToken) in d:\a\1\s\libraries\Microsoft.Bot.Builder.Dialogs\ComponentDialog.cs:line 86
   at Microsoft.Bot.Builder.Dialogs.DialogContext.ContinueDialogAsync(CancellationToken cancellationToken) in d:\a\1\s\libraries\Microsoft.Bot.Builder.Dialogs\DialogContext.cs:line 160
   at TestCosmosBot.TestCosmosBotBot.OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) in C:\Users\v-eridah\source\repos\TestCosmosBot\TestCosmosBot\TestCosmosBotBot.cs:line 125
   at Microsoft.Bot.Builder.BotFrameworkAdapter.TenantIdWorkaroundForTeamsMiddleware.OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken) in d:\a\1\s\libraries\Microsoft.Bot.Builder\BotFrameworkAdapter.cs:line 964
   at Microsoft.Bot.Builder.MiddlewareSet.ReceiveActivityWithStatusAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) in d:\a\1\s\libraries\Microsoft.Bot.Builder\MiddlewareSet.cs:line 55
   at Microsoft.Bot.Builder.BotAdapter.RunPipelineAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) in d:\a\1\s\libraries\Microsoft.Bot.Builder\BotAdapter.cs:line 167

Perhaps it's this cast right here: https://github.com/Microsoft/botbuilder-dotnet/blob/4.4/libraries/Microsoft.Bot.Builder.Dialogs/Prompts/Prompt.cs#L90

Perhaps CosmosDB stores the counter as an Int64 by default and so that's how it gets read.

That line was introduced very recently: https://github.com/Microsoft/botbuilder-dotnet/pull/1774/files#diff-1bbbc8f550395adfa5f014863009e56dR90

I presume the counter is being cast from an object to an integer so that arithmetic can be performed on it, but it wasn't considered what size of integer it should be. I wonder if there's some recommended way this kind of situation is meant to be handled. We could cast it as a long instead, or we could use Convert.ToInt32.

https://github.com/Microsoft/botbuilder-dotnet/blob/master/libraries/Microsoft.Bot.Builder.Dialogs/WaterfallDialog.cs#L112

        // For issue https://github.com/Microsoft/botbuilder-dotnet/issues/871
        // See the linked issue for details. This issue was happening when using the CosmosDB
        // data store for state. The stepIndex which was an object being cast to an Int64
        // after deserialization was throwing an exception for not being Int32 datatype.
        // This change ensures the correct datatype conversion has been done.
        var index = Convert.ToInt32(state[StepIndex]);

we're cutting a 4.4.1 release of the C# SDK to address this issue.

Just confirmed this is now working in 4.4.1

Great work!

Thank you for reporting this @NiteLordz

Was this page helpful?
0 / 5 - 0 ratings