{"record":{"id":"1c9b6a6d119edea3","repo":"tursodatabase/turso","slug":"turso-sync-connection-ownership-is-unbalanced","errorCode":null,"errorMessage":"Turso sync connection ownership is unbalanced.","messagePattern":"Turso sync connection ownership is unbalanced\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoSyncDatabase.cs","lineNumber":315,"sourceCode":"                    TursoSyncOperationKind.Connect,\n                    cancellationToken)\n                .ConfigureAwait(false);\n            EnsureResultKind(operation, TursoSyncOperationResultKind.Connection);\n            var connectionHandle = TursoSyncBindings.ExtractConnection(_handle, operation);\n            Interlocked.Increment(ref _activeConnections);\n            return connectionHandle;\n        }\n        finally\n        {\n            _operationLock.Release();\n        }\n    }\n\n    internal void ReleaseConnection()\n    {\n        var remaining = Interlocked.Decrement(ref _activeConnections);\n        if (remaining < 0)\n            throw new InvalidOperationException(\"Turso sync connection ownership is unbalanced.\");\n        if (remaining == 0 && Volatile.Read(ref _disposeRequested) != 0)\n            DisposeResources();\n    }\n\n    private async Task RunVoidOperationAsync(\n        Func<TursoSyncDatabaseHandle, TursoSyncOperationHandle> start,\n        TursoSyncOperationKind operationKind,\n        CancellationToken cancellationToken)\n    {\n        ThrowIfDisposed();\n        await _operationLock.WaitAsync(cancellationToken).ConfigureAwait(false);\n        try\n        {\n            ThrowIfDisposed();\n            using var operation = StartOperation(start, operationKind);\n            await DriveOperationAsync(operation, operationKind, cancellationToken).ConfigureAwait(false);\n            EnsureResultKind(operation, TursoSyncOperationResultKind.None);\n        }","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data/TursoSyncDatabase.cs#L297-L333","documentation":"TursoSyncDatabase tracks connection ownership with an atomic counter (_activeConnections). ReleaseConnection() decrements it and throws InvalidOperationException if the count would go negative, which indicates a bug: a Release without a matching Connect — an internal bookkeeping invariant violation rather than a user configuration problem.","triggerScenarios":"ReleaseConnection() called (via ConnectAsync's cleanup path) more times than ConnectAsync succeeded incrementing _activeConnections — e.g. double-release on a failure path or releasing after disposal raced the connect.","commonSituations":"Races between connection close/dispose and concurrent connect attempts; calling internal release APIs from custom wrapper code around TursoSyncDatabase.","solutions":["Check custom code for duplicate ReleaseConnection() calls or calling it without a prior successful Connect.","Ensure Dispose is not racing concurrent Connect/Release calls; serialize disposal with connection lifecycle.","If reproducible, report as a driver bug with a stack trace — this is an internal invariant violation."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    connection.Close();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"ownership is unbalanced\"))\n{\n    _logger.LogError(ex, \"Driver bug: unbalanced connection ownership. Report with stack trace.\");\n}","preventionTips":["Never call internal Release-style APIs more than once per successful connect.","Serialize Dispose with concurrent connect/close operations.","Treat this as a driver bug and file a report with a reproducible trace."],"tags":["dotnet","internal-state","concurrency","lifecycle"],"backgroundTag":"connection-ownership-unbalanced","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-08-31T11:17:35.598Z","contentChangedAt":"2026-08-31T11:17:35.598Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}