tursodatabase/turso · error · TursoSyncNativeException

{native error message via Marshal.PtrToStringUTF8}

Error message

{native error message via Marshal.PtrToStringUTF8}

What it means

This is the catch-all native interop exception in the .NET Turso sync bindings. When a P/Invoke call into the native tursodb library returns a non-zero error pointer or a non-OK status code, ThrowException converts the native UTF-8 error string into a managed TursoSyncNativeException carrying the status code and the native message. It means the failure originated inside the native library (SQL error, invalid handle, sync failure), not in the managed wrapper.

Source

Thrown at bindings/dotnet/src/Turso.Raw/Public/TursoSyncBindings.cs:466

        => slice.Length == 0 ? string.Empty : Encoding.UTF8.GetString(CopyBytes(slice));

    private static void ThrowIfError(TursoStatusCode status, IntPtr errorPtr)
    {
        if (errorPtr != IntPtr.Zero)
            ThrowException(status, errorPtr);
        if (status == TursoStatusCode.Ok)
            return;

        throw new TursoSyncNativeException(
            (uint)status,
            $"Turso sync native call failed with status {status}.");
    }

    private static void ThrowException(TursoStatusCode status, IntPtr errorPtr)
    {
        var message = Marshal.PtrToStringUTF8(errorPtr) ?? "Internal error";
        TursoSyncInterop.FreeString(errorPtr);
        throw new TursoSyncNativeException((uint)status, message);
    }

    private static void ReleaseConnection(IntPtr connection)
    {
        _ = TursoInterop.ConnectionClose(connection, out var errorPtr);
        if (errorPtr != IntPtr.Zero)
            TursoInterop.FreeString(errorPtr);
        TursoInterop.ConnectionDeinit(connection);
    }

    private sealed class NativeUtf8String : IDisposable
    {
        private NativeUtf8String(IntPtr pointer) => Pointer = pointer;

        public IntPtr Pointer { get; private set; }

        public static NativeUtf8String From(string? value)
            => new(value is null ? IntPtr.Zero : Marshal.StringToCoTaskMemUTF8(value));

View on GitHub (pinned to c1e5928725)

Solutions

  1. Read the exception's message and status code: the native message is the real diagnostic, not the .NET stack trace.
  2. Check the surrounding code for use-after-close/dispose of the connection or cursor before the failing call.
  3. Reproduce the same SQL/operation in the tursodb CLI to see if the native engine itself rejects it (vs a binding misuse).
  4. Verify the native tursodb binary matches the version the .NET bindings were compiled against; re-pin the package versions.
  5. Wrap calls in try/catch on TursoSyncNativeException and inspect the status code for retryable (I/O) vs permanent (SQL) errors.

Example fix

// before
connection.Execute(sql); // may throw TursoSyncNativeException with raw native message
// after
try
{
    connection.Execute(sql);
}
catch (TursoSyncNativeException ex)
{
    Console.Error.WriteLine($"Turso native error {ex.StatusCode}: {ex.Message}");
    if (!IsRetryable(ex.StatusCode)) throw;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify handle liveness before native calls
if (connection.IsClosed) throw new InvalidOperationException("connection already closed");

Type guard

static bool HasNativeError(IntPtr errorPtr) => errorPtr != IntPtr.Zero;

Try / catch

try
{
    nativeCall();
}
catch (TursoSyncNativeException ex)
{
    // ex.StatusCode distinguishes retryable I/O from permanent SQL errors
    Log(ex.StatusCode, ex.Message);
    if (!IsRetryable(ex.StatusCode)) throw;
}

Prevention

When it happens

Trigger: Any call into the raw sync bindings (Resume, cursor/step calls, sync operations) where the native side returns an errorPtr or status != Ok. E.g. executing SQL with a syntax error on a native connection, using a closed/disposed connection handle, or a native sync failure.

Common situations: SQL syntax or constraint violations raised by the engine, calling methods after the connection was closed or freed, native library version mismatch with the managed wrapper, or platform-specific native failures (file I/O, locking) surfaced through the error pointer.

Related errors


AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31). Data as JSON: /api/errors/3b7889a210d98ac9. Report an issue: GitHub.