{"record":{"id":"08c75084acd8a984","repo":"tursodatabase/turso","slug":"parameter-type-valuetype-is-not-supported","errorCode":null,"errorMessage":"Parameter type {valueType} is not supported","messagePattern":"Parameter type (.+?) is not supported","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoParameter.cs","lineNumber":103,"sourceCode":"    public override object? Value { get; set; }\n    public override bool SourceColumnNullMapping { get; set; }\n\n    public TursoValue ToValue()\n    {\n        if (Value is null)\n            return new TursoValue { ValueType = TursoValueType.Null };\n\n        var value = Value;\n        var valueType = value.GetType();\n        if (valueType.IsEnum)\n        {\n            valueType = Enum.GetUnderlyingType(valueType);\n            value = Convert.ChangeType(value, valueType, CultureInfo.InvariantCulture);\n        }\n\n        if (!TursoTypeMapping.TryGetValue(valueType, out var tursoValueType))\n        {\n            throw new ArgumentException($\"Parameter type {valueType} is not supported\");\n        }\n\n        return GetTursoValue(value, tursoValueType);\n    }\n\n    public override int Size\n    {\n        get => _size;\n        set\n        {\n            ArgumentOutOfRangeException.ThrowIfLessThan(value, -1);\n            _size = value;\n        }\n    }\n\n    private static TursoValue GetTursoValue(object value, TursoValueType tursoValueType)\n    {\n        return tursoValueType switch","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data/TursoParameter.cs#L85-L121","documentation":"TursoParameter.ToValue() converts the parameter's CLR Value into a TursoValue using a fixed type map; this ArgumentException fires when the runtime type of Value is not in the map. Supported types are: bool, byte, byte[], char, DateTime, DateTimeOffset, DateOnly, TimeOnly, DBNull, decimal, double, float, Guid, int, long, sbyte, short, string, TimeSpan, uint, ulong, ushort. Null converts to Turso NULL; everything else (enums, BigInteger, JsonElement, custom types) is rejected.","triggerScenarios":"Assigning a parameter value whose GetType() is outside the map — e.g. an enum value, System.Text.Json.JsonElement, BigInteger, Microsoft.Data.Sqlite.SqlString, an anonymous/custom POCO, or a dynamic/ulong overflow value — and then executing the command (ExecuteNonQuery/Reader/Scalar calls ToValue during binding).","commonSituations":"Passing enum properties directly from domain models; deserializing JSON config into JsonElement and binding it; porting code from providers with broader type support (SqlClient maps SqlTypes, Npgsql maps many primitive types); nullable wrapper types like 'int?' boxed with a value but typed helpers producing custom numeric types.","solutions":["Convert before binding: enums via Convert.ToInt64/ToString, JsonElement via .ToString() or GetRawText(), custom objects via an explicit serialization you control.","For blobs use byte[]; for decimal/dates the provider already stringifies supported types, so just use the base CLR types.","Wrap third-party numeric types with a cast to long/double/string at the call site."],"exampleFix":"// before\ncmd.Parameters.AddWithValue(\"@status\", OrderStatus.Shipped); // enum -> not in map\n\n// after\ncmd.Parameters.AddWithValue(\"@status\", (long)OrderStatus.Shipped);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static readonly HashSet<Type> Supported = new()\n{ typeof(bool), typeof(byte), typeof(byte[]), typeof(char), typeof(DateTime), typeof(DateTimeOffset),\n  typeof(DateOnly), typeof(TimeOnly), typeof(DBNull), typeof(decimal), typeof(double), typeof(float),\n  typeof(Guid), typeof(int), typeof(long), typeof(sbyte), typeof(short), typeof(string),\n  typeof(TimeSpan), typeof(uint), typeof(ulong), typeof(ushort) };\nstatic bool IsSupportedParameterValue(object? v) => v is null || Supported.Contains(v.GetType());","tryCatchPattern":"try { cmd.ExecuteNonQuery(); } catch (ArgumentException ex) when (ex.Message.Contains(\"Parameter type\")) { /* identify the parameter, convert its value to a base CLR type */ }","preventionTips":["Centralize parameter creation in one helper that converts enums/custom types to long, double, string, or byte[].","Add a startup unit test over the types your models bind."],"tags":["csharp","dotnet","parameters","type-mapping","serialization"],"backgroundTag":"unsupported-parameter-type","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-09-06T07:15:26.990Z","contentChangedAt":"2026-09-06T07:15:26.990Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}