tursodatabase/turso · error · TursoSyncException
Turso sync ${operation} failed: ${message}
Error message
Turso sync ${operation} failed: ${message} What it means
DriveOperationAsync pumps a native Turso sync operation to completion; when any unexpected exception escapes the resume/IO loop (other than TursoSyncException or cancellation), it is wrapped via CreateSyncException into 'Turso sync <operation> failed: <message>' with the operation kind (pull, stats, connect, etc.). It signals that the sync operation could not complete, with the inner exception carrying the root cause.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoSyncDatabase.cs:382
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
try
{
CancelQueuedIo();
}
catch
{
// Preserve cancellation after making the best effort to release native callbacks.
}
throw;
}
catch (TursoSyncException)
{
throw;
}
catch (Exception exception)
{
throw CreateSyncException(operationKind, exception);
}
}
private TursoSyncOperationHandle StartOperation(
Func<TursoSyncDatabaseHandle, TursoSyncOperationHandle> start,
TursoSyncOperationKind operationKind)
{
_lastTransportContext = null;
try
{
return start(_handle);
}
catch (TursoSyncException)
{
throw;
}
catch (Exception exception)
{View on GitHub (pinned to 6c72522679)
Solutions
- Read the InnerException of the TursoSyncException to find the root cause and fix that (network, file, or state issue).
- Ensure the database handle is not disposed or used concurrently while sync operations run.
- Retry the operation; transient IO/network failures during pull are common.
- Catch TursoSyncException specifically around sync calls and apply backoff/reconnect logic.
Example fix
// before
await db.PullAsync(); // raw, crashes on unexpected failure
// after
try { await db.PullAsync(); }
catch (TursoSyncException ex) { log(ex.Message, ex.InnerException); await ReconnectAndRetry(db); } Defensive patterns
Strategy: try-catch
Validate before calling
if (db.IsDisposed) throw new InvalidOperationException("TursoSyncDatabase disposed before sync");
ObjectDisposedException.ThrowIf(!_handle.IsInvalid, _handle); Type guard
static bool HasRootCause(TursoSyncException ex, Type t) =>
ex.InnerException is not null && t.IsInstanceOfType(ex.InnerException); Try / catch
try { await db.PullAsync(token); }
catch (TursoSyncException ex) when (ex.InnerException is IOException or ObjectDisposedException) {
logger.LogWarning(ex, "sync pull failed: {Msg}", ex.Message);
await Task.Delay(TimeSpan.FromSeconds(2), token);
} Prevention
- Always catch TursoSyncException around sync calls and log InnerException
- Do not dispose the database while sync operations are in flight
- Serialize sync operations; avoid concurrent PullAsync/ApplyOperation on one handle
- Retry transient failures with exponential backoff
When it happens
Trigger: Calling PullAsync, GetStatsAsync, ConnectHandleAsync, or a void sync operation when the underlying native binding or IO queue throws a non-TursoSyncException: invalid handle/state, IO callbacks failing, or an unexpected InvalidOperationException (e.g. unknown operation state).
Common situations: Disposing the TursoSyncDatabase while a pull is in flight; native library load problems; transport/IO handler throwing during ProcessIoQueueAsync; race conditions around the handle from another thread.
Related errors
- Sync requires an embedded replica connection.
- Turso batch execution requires a direct remote or embedded r
- Sync Interval must be between 0 and {MaximumSyncIntervalSeco
- 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-31).
Data as JSON: /api/errors/8d51cac91337a606.
Report an issue: GitHub.