diff --git a/dotnet/samples/04-hosting/DurableWorkflows/AzureFunctions/01_SequentialWorkflow/README.md b/dotnet/samples/04-hosting/DurableWorkflows/AzureFunctions/01_SequentialWorkflow/README.md
index 4e2a98dc7a..4f455b3dec 100644
--- a/dotnet/samples/04-hosting/DurableWorkflows/AzureFunctions/01_SequentialWorkflow/README.md
+++ b/dotnet/samples/04-hosting/DurableWorkflows/AzureFunctions/01_SequentialWorkflow/README.md
@@ -107,7 +107,7 @@ curl -X POST http://localhost:7071/api/workflows/CancelOrder/run \
```json
{
"runId": "abc123def456",
- "status": "Completed",
+ "workflowStatus": "Completed",
"result": "Cancellation email sent for order 12345 to jerry@example.com."
}
```
diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/BuiltInFunctions.cs b/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/BuiltInFunctions.cs
index 0717c989d7..376f2fa2ca 100644
--- a/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/BuiltInFunctions.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Hosting.AzureFunctions/BuiltInFunctions.cs
@@ -445,15 +445,28 @@ internal static class BuiltInFunctions
if (metadata is null)
{
- return await CreateErrorResponseAsync(req, context, HttpStatusCode.InternalServerError,
- $"Workflow orchestration '{instanceId}' returned no metadata.", acceptsJson);
+ return await CreateErrorResponseAsync(req, context, HttpStatusCode.NotFound,
+ $"No workflow orchestration with ID '{instanceId}' was found.", acceptsJson);
}
if (metadata.RuntimeStatus is OrchestrationRuntimeStatus.Failed)
{
string errorMessage = metadata.FailureDetails?.ErrorMessage ?? "Unknown error";
- return await CreateErrorResponseAsync(req, context, HttpStatusCode.InternalServerError,
- $"Workflow orchestration '{instanceId}' failed: {errorMessage}", acceptsJson);
+ HttpResponseData failedResponse = req.CreateResponse(HttpStatusCode.OK);
+
+ if (acceptsJson)
+ {
+ await failedResponse.WriteAsJsonAsync(
+ new WorkflowRunResponse(instanceId, metadata.RuntimeStatus.ToString(), Result: null, Error: errorMessage),
+ context.CancellationToken);
+ }
+ else
+ {
+ failedResponse.Headers.Add("Content-Type", "text/plain");
+ await failedResponse.WriteStringAsync(errorMessage, context.CancellationToken);
+ }
+
+ return failedResponse;
}
if (metadata.RuntimeStatus is not OrchestrationRuntimeStatus.Completed)
@@ -490,7 +503,9 @@ internal static class BuiltInFunctions
}
}
- await response.WriteAsJsonAsync(new WorkflowRunSuccessResponse(instanceId, metadata.RuntimeStatus.ToString(), resultElement), context.CancellationToken);
+ await response.WriteAsJsonAsync(
+ new WorkflowRunResponse(instanceId, metadata.RuntimeStatus.ToString(), resultElement),
+ context.CancellationToken);
}
else
{
@@ -687,15 +702,17 @@ internal static class BuiltInFunctions
[property: JsonPropertyName("response")] JsonElement Response);
///
- /// Represents a successful workflow run response when waiting for completion.
+ /// Represents a workflow run response when waiting for completion.
///
/// The orchestration run ID.
- /// The orchestration runtime status.
+ /// The orchestration runtime status (e.g., "Completed", "Failed").
/// The workflow result as a JSON element so POCOs serialize as nested objects rather than escaped strings.
- private sealed record WorkflowRunSuccessResponse(
+ /// An optional error message when the workflow has failed.
+ private sealed record WorkflowRunResponse(
[property: JsonPropertyName("runId")] string RunId,
- [property: JsonPropertyName("status")] string Status,
- [property: JsonPropertyName("result")] JsonElement? Result);
+ [property: JsonPropertyName("workflowStatus")] string WorkflowStatus,
+ [property: JsonPropertyName("result")] JsonElement? Result,
+ [property: JsonPropertyName("error"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] string? Error = null);
///
/// A service provider that combines the original service provider with an additional DurableTaskClient instance.
diff --git a/dotnet/tests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests/WorkflowSamplesValidation.cs b/dotnet/tests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests/WorkflowSamplesValidation.cs
index 435627a169..2eba009c67 100644
--- a/dotnet/tests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests/WorkflowSamplesValidation.cs
+++ b/dotnet/tests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests/WorkflowSamplesValidation.cs
@@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Reflection;
using System.Text;
+using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Client;
@@ -141,6 +142,29 @@ public sealed class WorkflowSamplesValidation(ITestOutputHelper outputHelper) :
// The response should contain the workflow result (not just "started for CancelOrder")
Assert.DoesNotContain("Workflow orchestration started", waitResponseText);
Assert.Contains("55555", waitResponseText);
+
+ // Test the wait-for-response with Accept: application/json header
+ this._outputHelper.WriteLine("Starting CancelOrder workflow with x-ms-wait-for-response and Accept: application/json...");
+
+ using HttpRequestMessage jsonWaitRequest = new(HttpMethod.Post, cancelOrderUri);
+ jsonWaitRequest.Content = new StringContent("77777", Encoding.UTF8, "text/plain");
+ jsonWaitRequest.Headers.Add("x-ms-wait-for-response", "true");
+ jsonWaitRequest.Headers.Add("Accept", "application/json");
+
+ using CancellationTokenSource jsonWaitCts = new(s_orchestrationTimeout);
+ using HttpResponseMessage jsonWaitResponse = await s_sharedHttpClient.SendAsync(jsonWaitRequest, jsonWaitCts.Token);
+
+ Assert.True(jsonWaitResponse.IsSuccessStatusCode, $"CancelOrder JSON wait-for-response request failed with status: {jsonWaitResponse.StatusCode}");
+ string jsonWaitResponseText = await jsonWaitResponse.Content.ReadAsStringAsync();
+ this._outputHelper.WriteLine($"CancelOrder JSON wait-for-response result: {jsonWaitResponseText}");
+
+ using JsonDocument jsonDoc = JsonDocument.Parse(jsonWaitResponseText);
+ JsonElement root = jsonDoc.RootElement;
+ Assert.True(root.TryGetProperty("runId", out _), "JSON response missing 'runId' property");
+ Assert.True(root.TryGetProperty("workflowStatus", out JsonElement statusEl), "JSON response missing 'workflowStatus' property");
+ Assert.Equal("Completed", statusEl.GetString());
+ Assert.True(root.TryGetProperty("result", out JsonElement resultEl), "JSON response missing 'result' property");
+ Assert.Contains("77777", resultEl.GetString());
});
}