Azure / Azure/azure-functions-dotnet-worker
FunctionInputConverterException when binding integer path parameters with leading zeros in Isolated Worker
- Dominant language
- C#
- Stars
- 466
- Forks
- 215
- Avg merge
- 3d 10h
- Merged PRs (30d)
- 7
Description
### Description
I am encountering an issue when binding a route parameter to an int argument in an Azure Function using the Isolated Worker model. If the path parameter in the URL contains a leading zero (e.g., 01), the binding fails with a FunctionInputConverterException wrapping a System.Text.Json.JsonException.
It appears that the input converter is treating the path parameter as a JSON number and System.Text.Json is rejecting the leading zero, whereas standard URL routing usually handles this gracefully by parsing the integer value.
### Steps to reproduce
1. Create a new Azure Functions project using the Isolated Worker model (.NET 8).
2. Create a function with an HTTP trigger and a route constraint for an integer:
```csharp
[Function("Function1")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "test/{id:int}")] HttpRequest req, int id)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult("Welcome to Azure Functions!");
}
```
3. Run the function locally.
4. Send a request with a leading zero in the ID: `curl -X GET "http://localhost:7071/api/test/01"`
**Expected behavior**
The function should execute successfully, and the id parameter should be bound to the integer value 1.
**Actual behavior**
The function invocation fails with the following exception:
```
[2025-12-03T16:24:39.551Z] Function 'Function1', Invocation id '...': An exception was thrown by the invocation.
Type:
Exception: Microsoft.Azure.Functions.Worker.FunctionInputConverterException: Error converting 1 input parameters for Function 'Function1': Cannot convert input parameter 'id' to type 'System.Int32' from type 'System.String'. Error:System.Text.Json.JsonException: Invalid leading zero before '0'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
[2025-12-03T16:24:39.557Z] ---> System.Text.Json.JsonReaderException: Invalid leading zero before '0'. LineNumber: 0 | BytePositionInLine: 1.
[2025-12-03T16:24:39.561Z] at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
[2025-12-03T16:24:39.564Z] at System.Text.Json.Utf8JsonReader.ConsumeZero(ReadOnlySpan`1& data, Int32& i)
[2025-12-03T16:24:39.568Z] at System.Text.Json.Utf8JsonReader.TryGetNumber(ReadOnlySpan`1 data, Int32& consumed)
[2025-12-03T16:24:39.570Z] at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first)
[2025-12-03T16:24:39.573Z] at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
[2025-12-03T16:24:39.575Z] at System.Text.Json.Utf8JsonReader.Read()
[2025-12-03T16:24:39.579Z] at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
[2025-12-03T16:24:39.581Z] --- End of inner exception stack trace ---
[2025-12-03T16:24:39.583Z] at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, JsonReaderException ex)
[2025-12-03T16:24:39.585Z] at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
[2025-12-03T16:24:39.587Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.ContinueDeserialize[TReadBufferState,TStream](TReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, T& value)
[2025-12-03T16:24:39.590Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsync[TReadBufferState,TStream](TStream utf8Json, TReadBufferState bufferState, CancellationToken cancellationToken)
[2025-12-03T16:24:39.592Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken)
[2025-12-03T16:24:39.594Z] at Microsoft.Azure.Functions.Worker.Converters.JsonPocoConverter.GetConversionResultFromDeserialization(Byte[] bytes, Type type) in /_/src/DotNetWorker.Core/Converters/JsonPocoConverter.cs:line 66
[2025-12-03T16:24:39.596Z] at Microsoft.Azure.Functions.Worker.Context.Features.DefaultFunctionInputBindingFeature.BindFunctionInputAsync(FunctionContext context) in /_/src/DotNetWorker.Core/Context/Features/DefaultFunctionInputBindingFeature.cs:line 97
[2025-12-03T16:24:39.598Z] at FunctionApp5.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in E:\trash\FunctionApp5\FunctionApp5\obj\Debug\net8.0\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 31
[2025-12-03T16:24:39.600Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /_/src/DotNetWorker.Core/OutputBindings/OutputBindingsMiddleware.cs:line 13
[2025-12-03T16:24:39.602Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /_/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 54
[2025-12-03T16:24:39.605Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in /_/src/DotNetWorker.Core/FunctionsApplication.cs:line 96
Stack: at Microsoft.Azure.Functions.Worker.Context.Features.DefaultFunctionInputBindingFeature.BindFunctionInputAsync(FunctionContext context) in /_/src/DotNetWorker.Core/Context/Features/DefaultFunctionInputBindingFeature.cs:line 97
[2025-12-03T16:24:39.607Z] at FunctionApp5.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in E:\trash\FunctionApp5\FunctionApp5\obj\Debug\net8.0\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 31
[2025-12-03T16:24:39.610Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /_/src/DotNetWorker.Core/OutputBindings/OutputBindingsMiddleware.cs:line 13
[2025-12-03T16:24:39.612Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /_/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 54
[2025-12-03T16:24:39.614Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in /_/src/DotNetWorker.Core/FunctionsApplication.cs:line 96.
```
### Environment
- **Worker Model:** Isolated Worker
- **Framework:** .NET 8.0
- **Package version:** :
- Microsoft.Azure.Functions.Worker, Version "2.51.0"
- Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore, Version "2.1.0"
- Microsoft.Azure.Functions.Worker.Sdk, Version "2.0.7"
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the .NET 8 isolated-worker request with curl, then inspect DotNetWorker.Core/Converters/JsonPocoConverter.cs at the reported line 66 and the input-binding path shown in the stack trace. Done means a route value of 01 is successfully bound to the integer value 1 without a FunctionInputConverterException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100