tursodatabase/turso · error · TursoException
Turso native call failed with status {status}.
Error message
Turso native call failed with status {status}. What it means
ThrowIfError is the shared exit check for all native P/Invoke calls in TursoBindings: statuses Ok/Done/Row pass, an error-string pointer produces a native message, and everything else throws TursoException carrying the raw status enum name (e.g. Busy, Io, Interrupt). This variant appears when native code fails without returning an error string, so the status code is all the diagnostics you get.
Source
Thrown at bindings/dotnet/src/Turso.Raw/Public/TursoBindings.cs:433
{
var data = new ReadOnlySpan<byte>((void*)ptr, checked((int)length));
return data.ToArray();
}
}
private static UIntPtr ToNativeIndex(int index) => checked((UIntPtr)(ulong)index);
private static UIntPtr ToNativeLength(int length) => checked((UIntPtr)(ulong)length);
private static void ThrowIfError(TursoStatusCode status, IntPtr errorPtr, string? messagePrefix = null)
{
if (errorPtr != IntPtr.Zero)
ThrowException(errorPtr, messagePrefix);
if (status is TursoStatusCode.Ok or TursoStatusCode.Done or TursoStatusCode.Row)
return;
throw new TursoException($"Turso native call failed with status {status}.");
}
private static void ThrowException(IntPtr errorPtr, string? messagePrefix = null)
{
var errorMessage = Marshal.PtrToStringUTF8(errorPtr);
var exception = new TursoException($"{messagePrefix}{errorMessage ?? "Internal error"}");
TursoInterop.FreeString(errorPtr);
throw exception;
}
private sealed class NativeUtf8String : IDisposable
{
private NativeUtf8String(IntPtr pointer) => Pointer = pointer;
public IntPtr Pointer { get; private set; }
public static NativeUtf8String From(string? value)
{View on GitHub (pinned to 6c72522679)
Solutions
- Read the status name from the message to classify: Busy -> retry after backoff; Io -> check path, permissions, disk; Interrupt/Oom -> inspect app state and resources.
- For Busy, wrap statements in a bounded retry with exponential backoff and consider a busy timeout if the layer exposes one.
- Verify the database path is readable/writable and the volume has space.
- Ensure the native library shipped with the bindings version you reference (no partial upgrades).
Example fix
// before
var stmt = TursoBindings.PrepareStatement(db, sql); // may throw: Turso native call failed with status Busy.
// after
TursoStatementHandle stmt;
for (var attempt = 0; ; attempt++)
{
try { stmt = TursoBindings.PrepareStatement(db, sql); break; }
catch (TursoException ex) when (attempt < 3 && ex.Message.Contains("Busy"))
{
Thread.Sleep(100 << attempt);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight the conditions behind the common statuses if (!File.Exists(path)) throw new FileNotFoundException(path); if (!HasWriteAccess(Path.GetDirectoryName(path))) throw new UnauthorizedAccessException(path);
Try / catch
catch (TursoException ex)
{
if (ex.Message.Contains("Busy") && attempt < maxRetries) { await Task.Delay(backoff); continue; }
if (ex.Message.Contains("Io")) { /* verify path, permissions, disk space; do not retry blindly */ }
throw;
} Prevention
- Check file existence and write permissions before opening local databases.
- Serialize writers or use a single writer connection to avoid Busy storms.
- Retry only transient statuses (Busy, Io) with bounded exponential backoff.
- Upgrade native library and bindings together as one unit.
When it happens
Trigger: Any wrapped native operation failing silently: opening a database file you cannot read/write (Io), a locked/busy database during write contention (Busy), interrupted execution, out-of-memory conditions, or an unrecognized status from a version-mismatched native library.
Common situations: Concurrent writers on the same file causing busy failures; wrong file permissions or a read-only mount; disk full; container memory limits; partial upgrades where the native library returns statuses the bindings do not map.
Related errors
- statement is invalid
- database is invalid
- Parameter index {index} is too large.
- Unable to read native value bytes.
- Turso sync ${operation} failed: ${message}
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-20).
Data as JSON: /api/errors/7e3cb56671719b1e.
Report an issue: GitHub.