Skip to main content

Fixed: "error CS1593: Delegate 'RequestDelegate' does not take 2 arguments" in a Minimal API

· 5 min read
Jagdish Kumawat
Founder @ Dewiride

A small minimal API endpoint wouldn't compile: error CS1593: Delegate 'RequestDelegate' does not take 2 arguments. My lambda had two parameters, as lambdas do, so the message made no sense at first. It's about the lambda's return value: TypedResults.NotFound() and TypedResults.Ok(…) have different types, so C# can't tell what the lambda returns, and ends up trying a different MapGet overload.

What I Was Doing​

In a .NET 10 minimal API, I wrote an endpoint as a lambda, answering 404 or 200 with TypedResults:

src/Dewiride.Inventory.Api/Program.cs (temporary endpoint)
app.MapGet("/demo/ternary/{id:int}", async (int id, InventoryDbContext db) =>
{
var category = await db.Categories.FindAsync(id);
return category is null ? TypedResults.NotFound() : TypedResults.Ok(category.Name);
});

What I Expected​

Build succeeded.

What I Got​

Output (the path is shortened)
DemoEndpoints.cs(383,77): error CS1593: Delegate 'RequestDelegate' does not take 2 arguments

A terminal where dotnet build fails with error CS1593: Delegate 'RequestDelegate' does not take 2 arguments.

What I Checked​

What RequestDelegate is. A delegate that takes an HttpContext. MapGet has an overload for it, and my code doesn't use it, so the compiler had been trying overloads and reported the last one that failed.

What the documentation says. ASP.NET Core's responses page has this exact case: "The following method does not compile, because TypedResults.Ok and TypedResults.NotFound are declared as returning different types and the compiler won't attempt to infer the best matching type". And it gives the answer: "To use TypedResults, the return type must be fully declared; when the method is asynchronous, the declaration requires wrapping the return type in a Task<>."

Whether a method avoids it. Yes. The same return inside a named method with a declared return type compiles fine, which is how the rest of this API is written.

Why It Happens​

category is null ? A : B needs one type for both branches. NotFound and Ok<string> have no common type C# can pick, so the conditional has no type, and neither does the lambda. Without one, the lambda doesn't fit the MapGet overload that takes a general Delegate. The compiler then reports its attempt with RequestDelegate, which is why the message talks about arguments and not about types.

The Fix​

Declare the lambda's return type​

Keep TypedResults, and say what the lambda returns:

An endpoint with a declared return type
app.MapGet("/demo/ternary/{id:int}", async Task<Results<NotFound, Ok<string>>> (int id, InventoryDbContext db) =>
{
var category = await db.Categories.FindAsync(id);
return category is null ? TypedResults.NotFound() : TypedResults.Ok(category.Name);
});

Results<NotFound, Ok<string>> is from Microsoft.AspNetCore.Http.HttpResults. It says this endpoint gives one of those two answers, and both branches convert to it. This is the better choice, because the OpenAPI document learns both answers from it.

Or use Results instead of TypedResults​

An endpoint that uses Results
app.MapGet("/demo/ternary-results/{id:int}", async (int id, InventoryDbContext db) =>
{
var category = await db.Categories.FindAsync(id);
return category is null ? Results.NotFound() : Results.Ok(category.Name);
});

Every Results method returns IResult, so both branches already have the same type. It's shorter, but OpenAPI can't see what's inside. TypedResults vs Results shows the difference in the generated document.

After the Fix​

Both compile:

Output
Build succeeded.
0 Warning(s)
0 Error(s)

And the first one answers as intended:

Response (GET /demo/ternary/1)
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

"Cables"
Response (GET /demo/ternary/99)
HTTP/1.1 404 Not Found
Content-Type: application/problem+json

{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "Not Found",
"status": 404,
"traceId": "00-b49228ac85e5b57f161d3158982e486a-85406bfd0cc72d51-00"
}

A terminal where dotnet build succeeds, GET /demo/ternary/1 answers 200 OK with the category name, and GET /demo/ternary/99 answers 404 Not Found.

Common Mistakes​

MistakeWhat happensDo this instead
Looking for a wrong parameter countYour parameters are fineLook at what the lambda returns
Casting one branch to IResultIt compiles, but you lose the OpenAPI informationDeclare the return type
Mixing Results and TypedResults in one lambdaThe same error, or a harder onePick one
Forgetting Task<> on an async lambdaA different compile errorWrap the return type in Task<>

Troubleshooting​

SymptomLikely causeFix
CS1593: Delegate 'RequestDelegate' does not take 2 argumentsA lambda whose return type can't be worked outDeclare it
CS0173: Type of conditional expression cannot be determinedThe same mismatch, outside a lambdaDeclare the type you want
CS0029: Cannot implicitly convert type in a declared lambdaOne branch's type isn't in your Results<…>Add it to the list
Results<…> gives CS0308using Microsoft.AspNetCore.Http.HttpResults; is missingAdd it

FAQ​

Why does a single return statement work?​

With one TypedResults call, the lambda has one return type, so nothing needs working out. The problem starts at two different ones.

Are named methods better?​

For anything longer than a line or two, usually: the return type is required there anyway, and the endpoint gets a readable name. How to Move Minimal API Endpoints into Their Own Class shows it.

Conclusion​

error CS1593: Delegate 'RequestDelegate' does not take 2 arguments in a minimal API is rarely about arguments. Your lambda returns two different TypedResults types, so it has no type C# can work out. Declare it as async Task<Results<NotFound, Ok<string>>> (…) =>, or use Results, which always returns IResult.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.