github/copilot-sdk · error · JsonException

Expected string for ToolBinaryResultType.

Error message

Expected string for ToolBinaryResultType.

What it means

The ToolBinaryResultType JsonConverter.Read requires the incoming JSON token to be a string, since ToolBinaryResultType wraps a string value. It throws this JsonException for any other token type (number, object, array, etc.).

Solutions

  1. Ensure the JSON field is a string value matching a known ToolBinaryResultType.
  2. Verify the producing side's schema/version still emits strings.
  3. Make the property nullable if the field can be absent.
  4. Catch JsonException and report the payload path for debugging.

Example fix

// before
{"resultType": 1}
// after
{"resultType": "binary"}
Defensive patterns

Strategy: type-guard

Validate before calling

using var doc = JsonDocument.Parse(json);
if (doc.RootElement.GetProperty("resultType").ValueKind != JsonValueKind.String)
    throw new InvalidDataException("resultType must be a string");

Type guard

static bool IsJsonString(JsonElement e) => e.ValueKind == JsonValueKind.String;

Try / catch

try { result = JsonSerializer.Deserialize<ToolResult>(json); }
catch (JsonException ex) { log.LogError(ex, "ToolBinaryResultType token was not a string"); }

Prevention

When it happens

Trigger: Deserializing JSON where a tool binary result type field is not a string, e.g. `"resultType": 3` or `"resultType": {...}` passed to JsonSerializer.Deserialize of a model containing ToolBinaryResultType.

Common situations: Malformed payloads from external tool runners; schema drift where the field became numeric; hand-constructed JSON in tests.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/3c5f050b9681a045. Report an issue: GitHub.

Appendix: source

Thrown at dotnet/src/Types.cs:686

    /// <inheritdoc/>
    public bool Equals(ToolBinaryResultType other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase);

    /// <inheritdoc/>
    public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value);

    /// <inheritdoc/>
    public override string ToString() => Value;

    /// <summary>Provides a <see cref="JsonConverter{ToolBinaryResultType}"/> for serializing <see cref="ToolBinaryResultType"/> instances.</summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public sealed class Converter : JsonConverter<ToolBinaryResultType>
    {
        /// <inheritdoc/>
        public override ToolBinaryResultType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if (reader.TokenType != JsonTokenType.String)
            {
                throw new JsonException("Expected string for ToolBinaryResultType.");
            }

            var value = reader.GetString();
            if (value is null)
            {
                throw new JsonException("ToolBinaryResultType value cannot be null.");
            }

            return new ToolBinaryResultType(value);
        }

        /// <inheritdoc/>
        public override void Write(Utf8JsonWriter writer, ToolBinaryResultType value, JsonSerializerOptions options) =>
            writer.WriteStringValue(value.Value);
    }
}

/// <summary>

View on GitHub (pinned to cd8cf15dc3)