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
- Read the exception's message and status code: the native message is the real diagnostic, not the .NET stack trace.
- Check the surrounding code for use-after-close/dispose of the connection or cursor before the failing call.
- Reproduce the same SQL/operation in the tursodb CLI to see if the native engine itself rejects it (vs a binding misuse).
- Verify the native tursodb binary matches the version the .NET bindings were compiled against; re-pin the package versions.
- 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
- Always read the exception message — it carries the native library's diagnostic.
- Never use connection/cursor objects after Dispose.
- Keep the native binary and .NET binding versions in lockstep.
- Test the failing SQL directly in tursodb CLI to separate SQL errors from binding misuse.
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
- Embedded replica sync is not supported yet by the .NET provi
- Embedded replica connections are not supported yet by the .N
- Sync Interval requires embedded replica support, which is no
- Auth Token requires a remote Turso URL Data Source.
- Parameter {value} not found
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31).
Data as JSON: /api/errors/3b7889a210d98ac9.
Report an issue: GitHub.