tursodatabase/turso · error · InvalidCastException

Cannot convert {value.GetType()} value to Guid.

Error message

Cannot convert {value.GetType()} value to Guid.

What it means

ToGuid converts a column value to Guid, accepting Guid, string, or 16-byte binary (with a fallback parsing UTF-8 text). Any other runtime type reaches the switch's default arm and throws InvalidCastException, naming the offending type.

Source

Thrown at bindings/dotnet/src/Turso.Data/TursoDataReader.cs:438

                 || normalized.Contains("CLOB", StringComparison.Ordinal))
            fieldType = typeof(string);
        else if (normalized.Contains("BLOB", StringComparison.Ordinal))
            fieldType = typeof(byte[]);
        else
            return false;

        return true;
    }

    public static Guid ToGuid(object value)
    {
        return value switch
        {
            Guid guid => guid,
            string text => Guid.Parse(text),
            byte[] bytes when bytes.Length == 16 => new Guid(bytes),
            byte[] bytes => Guid.Parse(Encoding.UTF8.GetString(bytes)),
            _ => throw new InvalidCastException($"Cannot convert {value.GetType()} value to Guid.")
        };
    }

    private static DbType GetDbType(Type fieldType)
    {
        if (fieldType == typeof(long))
            return DbType.Int64;
        if (fieldType == typeof(double))
            return DbType.Double;
        if (fieldType == typeof(string))
            return DbType.String;
        if (fieldType == typeof(byte[]))
            return DbType.Binary;
        if (fieldType == typeof(Guid))
            return DbType.Guid;

        return DbType.Object;
    }

View on GitHub (pinned to 6c72522679)

Solutions

  1. Store UUIDs as TEXT or as exactly 16-byte BLOBs so GetGuid can convert.
  2. Convert in SQL: SELECT CAST(hex_col AS TEXT) or hex(blob_col) and parse on the client.
  3. Read the value as its native type (GetValue/GetInt64) and convert manually.
  4. Check the underlying type with reader.GetFieldType(ordinal) before calling GetGuid.

Example fix

// before
var id = reader.GetGuid(0); // column is INTEGER
// after
var id = reader.GetInt64(0);
var guid = new Guid(BitConverter.GetBytes(id)); // or fix storage to TEXT/16-byte BLOB
Defensive patterns

Strategy: type-guard

Validate before calling

var v = reader.GetValue(ordinal);
bool isGuidLike = v is Guid || (v is string) || (v is byte[] b && b.Length == 16);

Type guard

static bool CanReadAsGuid(object? value) => value is Guid or string or byte[] { Length: 16 };

Try / catch

try { guid = reader.GetGuid(ordinal); }
catch (InvalidCastException ex) when (ex.Message.EndsWith("value to Guid."))
{ guid = Guid.Parse(reader.GetValue(ordinal).ToString()!); }

Prevention

When it happens

Trigger: Calling reader.GetGuid(ordinal) on a column stored as INTEGER, REAL, or BLOB whose byte length is not 16 — e.g. a UUID stored as TEXT is fine, but one stored as a non-16-byte blob or an integer key is not.

Common situations: Reading a UUID column that was written by another client as an integer or 12/20-byte blob; schema drift where the column type changed; mapping a non-UUID column to a Guid property in an ORM.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06). Data as JSON: /api/errors/579b7dc058535453. Report an issue: GitHub.