tursodatabase/turso · error · InvalidOperationException
Embedded replica lease ownership is unbalanced.
Error message
Embedded replica lease ownership is unbalanced.
What it means
ReleaseReference decrements the reference count of a pooled embedded replica entry when a connection is disposed. The registry expects every Release to be paired with exactly one Acquire; if the count is already <= 0 the lease bookkeeping is corrupt, so it throws this InvalidOperationException to surface the internal bug.
Source
Thrown at bindings/dotnet/src/Turso.Data/TursoReplicaRegistry.cs:108
}
catch
{
lock (Gate)
{
if (Entries.TryGetValue(entry.Path, out var current) && ReferenceEquals(current, entry))
Entries.Remove(entry.Path);
}
throw;
}
}
private static Exception? ReleaseReference(Entry entry)
{
Holder? holder;
lock (Gate)
{
if (entry.ReferenceCount <= 0)
throw new InvalidOperationException("Embedded replica lease ownership is unbalanced.");
entry.ReferenceCount--;
if (entry.ReferenceCount != 0)
{
var status = entry.Holder?.Coordinator.Status;
return status?.State == TursoAutomaticSyncState.Faulted
? status.LastException
: null;
}
entry.Closing = true;
entry.InitializationCancellation.Cancel();
holder = entry.Holder;
if (holder is null)
{
_ = DisposeAfterInitializationAsync(entry);
return null;
}
}View on GitHub (pinned to 6c72522679)
Solutions
- Ensure each connection is disposed exactly once (don't call both Close and Dispose, don't dispose inside and outside a using block).
- Check for code that shares one TursoConnection across threads and disposes it concurrently.
- If it appears without obvious double-dispose, report it as a bug in Turso.Data reference counting.
- Guard disposal with an idempotent wrapper around your connection lifetime management.
Example fix
// before
tursoConn.Dispose();
// ... later, accidental second release
tursoConn.Dispose();
// after: single idempotent disposal
if (!tursoDisposed) { tursoConn.Dispose(); tursoDisposed = true; } Defensive patterns
Strategy: try-catch
Try / catch
try { tursoConn.Dispose(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("lease ownership is unbalanced"))
{
// bookkeeping bug or double dispose; log and stop touching this connection
} Prevention
- Dispose each connection exactly once; rely on using blocks rather than manual Close+Dispose.
- Never share a TursoConnection across threads without synchronization.
- Treat connection objects as single-owner; don't copy references and dispose twice.
When it happens
Trigger: Disposing/closing a TursoConnection that acquired an embedded replica lease more than once, releasing a reference after the entry was already fully released, or double-dispose racing with another dispose while ReferenceCount is already zero.
Common situations: Double disposal of the same connection (e.g. using-block plus explicit Dispose or finalizer path), copying a connection object and disposing both copies, a bug in custom pooling code that calls release APIs directly.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
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
- Pooling is not supported for embedded replica connections ye
- Automatic sync is not supported for embedded replica connect
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-09-06).
Data as JSON: /api/errors/32d6996b6fea7438.
Report an issue: GitHub.