dotnet/machinelearning · error · InvalidOperationException

Parameter name cannot be null

Error message

Parameter name cannot be null

What it means

BuildJsonSchemaFromFunctionContract converts a FunctionContract's parameters into a JSON schema for Mistral tool-calling. If a parameter's Name is null the method throws InvalidOperationException('Parameter name cannot be null'), since a JSON-schema property requires a name.

Solutions

  1. Set Name on every parameter of the FunctionContract before calling
  2. Validate parameters before building: skip or fix any with null Name
  3. If constructing contracts manually, use the constructor overload that requires a name

Example fix

// before
var param = new KernelParameterMetadata { ParameterType = typeof(string), Description = "city" };
// after
var param = new KernelParameterMetadata { Name = "city", ParameterType = typeof(string), Description = "city" };
Defensive patterns

Strategy: validation

Validate before calling

if (contract.Parameters?.Any(p => p.Name is null) == true)
    throw new ArgumentException("All function parameters must have a Name before schema building");

Try / catch

try { schema = BuildJsonSchemaFromFunctionContract(contract); }
catch (InvalidOperationException ex) { log.Error($"Bad parameter metadata on {contract.Name}", ex); throw; }

Prevention

When it happens

Trigger: Passing a FunctionContract whose Parameters collection contains a KernelParameterMetadata/parameter descriptor with a null Name — typically a manually constructed contract or one deserialized from incomplete metadata.

Common situations: Hand-writing FunctionContract with parameter metadata where only Description/ParameterType were set; dynamic generation of contracts from reflected methods whose parameter names were lost (e.g. out params or trimmed assemblies).

Related errors


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/8f405b214a93aaff. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.ML.GenAI.Mistral/Mistral_7B_0_3ChatTemplateBuilder.cs:177

        var toolCallMessage = message.Message1;
        var toolCallResultMessage = message.Message2;

        var toolCall = BuildFromToolCallMessage(toolCallMessage);
        var toolCallResult = BuildFromToolCallResultMessage(toolCallResultMessage);

        return $"{toolCall}{toolCallResult}";
    }

    private JsonSchema BuildJsonSchemaFromFunctionContract(FunctionContract contract)
    {
        var requiredParameterNames = new List<string>();
        var propertiesSchemas = new Dictionary<string, JsonSchema>();
        var propertySchemaBuilder = new JsonSchemaBuilder().Type(SchemaValueType.Object);
        foreach (var param in contract.Parameters ?? [])
        {
            if (param.Name is null)
            {
                throw new InvalidOperationException("Parameter name cannot be null");
            }

            var schemaBuilder = new JsonSchemaBuilder().FromType(param.ParameterType ?? throw new ArgumentNullException(nameof(param.ParameterType)));
            if (param.Description != null)
            {
                schemaBuilder = schemaBuilder.Description(param.Description);
            }

            if (param.IsRequired)
            {
                requiredParameterNames.Add(param.Name);
            }

            var schema = schemaBuilder.Build();
            propertiesSchemas[param.Name] = schema;

        }
        propertySchemaBuilder = propertySchemaBuilder.Properties(propertiesSchemas);

View on GitHub (pinned to 7b76e69cf9)