{"record":{"id":"9ab0c17229e89388","repo":"tursodatabase/turso","slug":"extensions-array-cannot-be-null","errorCode":null,"errorMessage":"Extensions array cannot be null.","messagePattern":"Extensions array cannot be null\\.","errorType":"exception","errorClass":"System.Text.Json.JsonException","httpStatus":null,"severity":"warning","filePath":"bindings/dotnet/src/Turso.Platform.Client/TursoPlatformClient.Supplement.cs","lineNumber":38,"sourceCode":"    {\n        ArgumentNullException.ThrowIfNull(names);\n        return new Extensions(names.ToArray());\n    }\n\n    /// <summary>The explicitly enabled extension names, or <see langword=\"null\"/> for <see cref=\"All\"/>.</summary>\n    public IReadOnlyList<string>? Names { get; }\n}\n\ninternal sealed class ExtensionsJsonConverter : System.Text.Json.Serialization.JsonConverter<Extensions>\n{\n    public override Extensions Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options)\n    {\n        return reader.TokenType switch\n        {\n            System.Text.Json.JsonTokenType.String when reader.GetString() == \"all\" => Extensions.All,\n            System.Text.Json.JsonTokenType.StartArray => Extensions.FromNames(\n                System.Text.Json.JsonSerializer.Deserialize<string[]>(ref reader, options)\n                ?? throw new System.Text.Json.JsonException(\"Extensions array cannot be null.\")),\n            _ => throw new System.Text.Json.JsonException(\"Extensions must be \\\"all\\\" or an array of extension names.\"),\n        };\n    }\n\n    public override void Write(System.Text.Json.Utf8JsonWriter writer, Extensions value, System.Text.Json.JsonSerializerOptions options)\n    {\n        if (value.Names is null)\n        {\n            writer.WriteStringValue(\"all\");\n            return;\n        }\n\n        System.Text.Json.JsonSerializer.Serialize(writer, value.Names, options);\n    }\n}\n","sourceCodeStart":20,"sourceCodeEnd":54,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/dotnet/src/Turso.Platform.Client/TursoPlatformClient.Supplement.cs#L20-L54","documentation":"ExtensionsJsonConverter deserializes the Platform API's Extensions union: the string \"all\", or an array of names. When the JSON token is an array but JsonSerializer.Deserialize<string[]> returns null, it throws JsonException with this message. A StartArray token essentially cannot produce null under normal options, so this is a defensive guard against degenerate input or interfering custom converters.","triggerScenarios":"Deserializing a request/response body where \"extensions\" is an array token that yields null — realistically only with custom JsonSerializerOptions string[] converters, malformed framing, or a hand-rolled reader pipeline; ordinary payloads like [] or [\"crypto\"] never take this path.","commonSituations":"Unit tests that share a JsonSerializerOptions instance with custom converters; intermediate middleware that rewrites bodies; virtually never seen from the real Platform API.","solutions":["Send well-formed payloads: \"extensions\": [\"crypto\",\"regexp\"] or \"extensions\": \"all\"; avoid null elements.","Build requests with the typed Extensions class (Extensions.All / Extensions.FromNames) instead of hand-writing JSON.","Use plain JsonSerializerOptions (web defaults) when deserializing Platform DTOs so the built-in converter behavior is not overridden.","If you wrap deserialization, validate the parsed array for null entries before proceeding."],"exampleFix":"// before\n{ \"extensions\": [null, \"crypto\"] }\n\n// after\n{ \"extensions\": [\"crypto\", \"regexp\"] }","handlingStrategy":"validation","validationCode":"// validate the extensions payload shape before deserializing\nusing var doc = JsonDocument.Parse(json);\nvar token = doc.RootElement.GetProperty(\"extensions\");\nbool ok = (token.ValueKind == JsonValueKind.String && token.GetString() == \"all\")\n       || (token.ValueKind == JsonValueKind.Array && token.EnumerateArray().All(e => e.ValueKind == JsonValueKind.String));","typeGuard":null,"tryCatchPattern":"try { var ext = JsonSerializer.Deserialize<Extensions>(json); }\ncatch (JsonException) { /* payload malformed: fix producer or reject request */ }","preventionTips":["Use the typed Extensions class instead of hand-built JSON.","Use default JsonSerializerOptions for Platform DTOs; do not attach custom string[] converters.","Never emit null entries in the extensions array."],"tags":["dotnet","json","platform-api","deserialization"],"backgroundTag":"json-deserialization-null","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}