tursodatabase/turso · error · InvalidCastException
Cannot convert remote {Type} value to Double.
Error message
Cannot convert remote {Type} value to Double. What it means
GetDouble on a reader column whose remote value type is not float, integer, or text. NULL and BLOB values have no conversion arm, so a NULL cell read with GetDouble throws InvalidCastException rather than yielding a default.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoRemoteClient.cs:687
public long GetInt64()
{
return Type switch
{
"integer" => ParseInteger(),
"float" => checked((long)ParseFloat()),
"text" => long.Parse(Value.GetString() ?? "", CultureInfo.InvariantCulture),
_ => throw new InvalidCastException($"Cannot convert remote {Type} value to Int64."),
};
}
public double GetDouble()
{
return Type switch
{
"float" => ParseFloat(),
"integer" => ParseInteger(),
"text" => double.Parse(Value.GetString() ?? "", CultureInfo.InvariantCulture),
_ => throw new InvalidCastException($"Cannot convert remote {Type} value to Double."),
};
}
public decimal GetDecimal()
{
return Type switch
{
"float" => Convert.ToDecimal(ParseFloat(), CultureInfo.InvariantCulture),
"integer" => ParseInteger(),
"text" => decimal.Parse(Value.GetString() ?? "", CultureInfo.InvariantCulture),
_ => throw new InvalidCastException($"Cannot convert remote {Type} value to Decimal."),
};
}
private long ParseInteger()
{
return Value.ValueKind == JsonValueKind.String
? long.Parse(Value.GetString() ?? "", CultureInfo.InvariantCulture)View on GitHub (pinned to 6c72522679)
Solutions
- Guard with reader.IsDBNull(i) before GetDouble and substitute 0.0 or double.NaN as appropriate.
- Use COALESCE/IFNULL in the SQL so the server never returns NULL for that column.
- Verify the column ordinal and underlying type before switching to typed getters.
- For text columns that should be numeric, parse manually with double.TryParse to control the failure mode.
Example fix
// before double avg = reader.GetDouble(0); // after double avg = reader.IsDBNull(0) ? 0.0 : reader.GetDouble(0);
Defensive patterns
Strategy: validation
Validate before calling
if (reader.IsDBNull(ordinal))
return 0.0; // or double.NaN as your domain sentinel
return reader.GetDouble(ordinal); Type guard
static bool CanReadDouble(System.Data.Common.DbDataReader reader, int i) =>
!reader.IsDBNull(i)
&& reader.GetFieldType(i) is Type t
&& (t == typeof(double) || t == typeof(long) || t == typeof(string)); Try / catch
try { value = reader.GetDouble(i); }
catch (InvalidCastException) when (reader.IsDBNull(i))
{
value = 0.0;
} Prevention
- Guard aggregates like AVG/MAX that return NULL on empty sets with COALESCE or IsDBNull checks.
- Verify the column type after any schema migration before keeping typed getters.
- Parse numeric-looking text columns with TryParse to control failures instead of letting casts throw.
- Read by column name, not ordinal, to survive column reordering.
When it happens
Trigger: reader.GetDouble(i) on a remote connection where column i is NULL, a BLOB, or an unsupported type; numeric-looking text goes through double.Parse, which throws FormatException for non-numeric strings instead.
Common situations: Aggregates returning NULL on empty sets (AVG over zero rows); nullable REAL columns read without null checks; schema drift turning a REAL column into TEXT or BLOB.
Related errors
- Cannot convert remote {Type} value to Int64.
- Cannot convert remote {Type} value to Decimal.
- Remote response returned unsupported value type: {Type}
- Embedded replica sync is not supported yet by the .NET provi
- Embedded replica connections are not supported yet by the .N
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-20).
Data as JSON: /api/errors/27239c17405f5348.
Report an issue: GitHub.