Open EmilDamsbo opened 6 months ago
This is incredibly strange. Does your app contain any customizations, like middleware, injected services, etc., - i.e. things that would normally be done in the Program.cs file?
I can't think of any reason why the trigger binding value would be an object, and why it would be a fully populated FunctionsOrchestrationContext
of all things as shown in your screenshot.
It would be great if you could provide a minimal repro app for us to look at.
We have quite a large app built around this, and there is potentially some middlewares at play. I'll work to produce a minimum repro of this within the week. Some additional context would also be that the caller to the orchestrator is an abstract generic class which the entrypoint function inherits.
So something like
public abstract class FunctionBase<TRequest>
{
protected async Task<IActionResult> DispatchJobFromRequest(TRequest request, DurableTaskClient context)
{
[...]
// using the generated extension method for class-based orchestrators, but this reproed without it too
// https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-dotnet-isolated-overview#source-generator-and-class-based-activities-and-orchestrations
await context.ScheduleNewDispatchJobInstanceAsync(request);
[...]
return new ObjectResult(...])
}
}
public class RequestHandler : FunctionBase<MyRequest>
{
[Function]
public async Task<IActionResult> HandleRequest([HttpTrigger([...])] HttpRequest request, [DurableClient] DurableTaskClient context)
{
MyRequest convertedRequest = [convert HttpRequest to MyRequest somehow]
return this.DispatchJobFromRequest(convertedRequest, context);
}
}
And the orchestrator function DispatchJob is defined elsewhere not inheriting from the FunctionBase
.
This is the source-generated extension for the DurableTaskClient (censored the namespace and part of the object name), and I don't see any reason why it would pass the fully-formed FunctionsOrchestrationContext
here.
It seems to be related to inheritance when passing objects as an input parameter to the ScheduleNewOrchestrationInstanceAsync
-method, because I now have a not-entirely-minimal repro. I will try to upload it tomorrow once I've removed any traces of company IP.
I found the offending line. I had previously followed some of the advice in this thread https://github.com/Azure/azure-functions-durable-extension/issues/2527
So the functions' HostBuilder looked like this:
var host = new HostBuilder()
.ConfigureFunctionsWebApplication(
builder => new DurableTaskExtensionStartup().Configure(builder)
)
.ConfigureServices(services =>
{
services.AddHttpClient();
})
.Build();
host.Run();
Now this manual call to DurableTaskExtensionStartup.Configure
had fixed some of my source generation issues, however it is also causing some unintended middleware issues unbeknownst to me. So when I removed line 3 there with the explicit DurableTaskExtensionStartup.Configure()
-call, I stopped encountering the issue.
Repository here demonstrates the issue. it's about as minimal as it gets, it's based on one of the public templates:
https://github.com/EmilDamsbo/OrchestrationInputBindingRepro
I recommend adding some kind of mechanism in DurableTaskExtensionStartup
to ensure there isn't duplicated middlewares.
@jviau can you take a look? This seems related to another issue that you've helped users with before.
@EmilDamsbo I imagine what happened is your source generation was eventually fixed, so that line: new DurableTaskExtensionStartup().Configure(builder)
was now being implicitly called for you. Having that manual call wound up double registering our types, leading to some undefined behavior.
I agree that this is most likely what happened after all my experimentation. Would it be possible to catch this DI double-registration on the durable extensions side or should I open an issue elswhere?
We could do some work on the durable side to make this registration re-enterable.
@EmilDamsbo - if you're still seeing the issue, can you provide a latest minimal repro please? We'd like to know what exactly is the trigger of the exception. Thanks!
Closing since the underlying issue has been fixed.
This issue still exists when using the new IHostApplicationBuilder
logic being introduced right now (currently in -preview2 versions of Azure Functions). The documentation says to setup the host like this:
var builder = FunctionsApplication.CreateBuilder(args);
// (...) removed because doesn't seem to matter?
var host = builder.Build();
And later calls for builder.ConfigureFunctionsWebApplication()
to be used to enable ASP.NET Core integration:
If you want to use ASP.NET Core integration, call builder.ConfigureFunctionsWebApplication().
However, the moment you add that ConfigureFunctionsWebApplication()
call, Durable Framework starts failing with:
Exception: System.InvalidOperationException: Orchestration history state was either missing from the input or not a string value.
To reproduce, simply create a new Azure Functions app with a Durable Function in it, update the SDKs to preview versions and change the host setup from
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();
host.Run();
to
var hostBuilder = FunctionsApplication.CreateBuilder(args);
hostBuilder.ConfigureFunctionsWebApplication();
var host = hostBuilder.Build();
host.Run();
The versions I've used to reproduce it:
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" /> <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0-preview4" /> <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.4.0" /> <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.7" /> <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" /> <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.0.0-preview4" /> <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0-preview2" />
Reactivating per @MarcinJuraszek as it seems like a new regression might have been introduced in some of the current preview nuget packages.
@jviau - any ideas what might be going on here?
Description
Running into the uncaught exception
"Orchestration history state was either missing from the input or not a string value"
.Setup
triggerInputData
is expected to have a.value
that is either null or string, but in my case it's a{Microsoft.Azure.Functions.Worker.Extensions.DurableTask.FunctionsOrchestrationContext}
. The wholetriggerInputData
object after binding:Expected behavior
I expect the orchestration trigger to bind successfully, and start executing my function code.
Actual behavior
Function 'DispatchJob (Orchestrator)' failed with an error. Reason: Orchestration history state was either missing from the input or not a string value.
Relevant source code snippets
Known workarounds
I haven't encountered any workarounds yet.
App Details
Screenshots