JamesNK/Newtonsoft.Json · error · ArgumentException

A name is required when setting property name state.

Error message

A name is required when setting property name state.

What it means

Thrown on the async path (JsonWriter.Async.cs) inside InternalWriteTokenAsync when a JsonToken.PropertyName is being written but the supplied value is not a string. JSON property names must be strings, so a non-string name is rejected with ArgumentException before the writer corrupts the output. This mirrors the synchronous guard in JsonWriter.cs.

Source

Thrown at Src/Newtonsoft.Json/JsonWriter.Async.cs:1666

        protected Task SetWriteStateAsync(JsonToken token, object value, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return cancellationToken.FromCanceled();
            }

            switch (token)
            {
                case JsonToken.StartObject:
                    return InternalWriteStartAsync(token, JsonContainerType.Object, cancellationToken);
                case JsonToken.StartArray:
                    return InternalWriteStartAsync(token, JsonContainerType.Array, cancellationToken);
                case JsonToken.StartConstructor:
                    return InternalWriteStartAsync(token, JsonContainerType.Constructor, cancellationToken);
                case JsonToken.PropertyName:
                    if (!(value is string s))
                    {
                        throw new ArgumentException("A name is required when setting property name state.", nameof(value));
                    }

                    return InternalWritePropertyNameAsync(s, cancellationToken);
                case JsonToken.Comment:
                    return InternalWriteCommentAsync(cancellationToken);
                case JsonToken.Raw:
                    return AsyncUtils.CompletedTask;
                case JsonToken.Integer:
                case JsonToken.Float:
                case JsonToken.String:
                case JsonToken.Boolean:
                case JsonToken.Date:
                case JsonToken.Bytes:
                case JsonToken.Null:
                case JsonToken.Undefined:
                    return InternalWriteValueAsync(token, cancellationToken);
                case JsonToken.EndObject:
                    return InternalWriteEndAsync(JsonContainerType.Object, cancellationToken);

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Always pass a string property name to WritePropertyName/WritePropertyNameAsync.
  2. When writing tokens via WriteTokenAsync, ensure PropertyName tokens carry a string value.
  3. Convert non-string keys (e.g. dictionary numeric keys) to string before emitting a property name.

Example fix

// before
await writer.WriteTokenAsync(JsonToken.PropertyName, 42);

// after
await writer.WritePropertyNameAsync("42");
Defensive patterns

Strategy: validation

Validate before calling

if (value is string name)
{
    await writer.WritePropertyNameAsync(name, escape: false);
}

Type guard

static bool IsValidPropertyName(object value) => value is string;

Prevention

When it happens

Trigger: Calling WritePropertyNameAsync with a non-string value, or routing a JsonToken.PropertyName token through an async write path (e.g. WriteTokenAsync / a JTokenWriter async copy) where the token's value object is not a string.

Common situations: Custom async writers or token pipelines passing boxed non-string values as property names; programmatically constructing tokens with numeric/object property names; copying JToken trees whose property names are not strings.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/6ec6392714fb223a. Report an issue: GitHub.