{"record":{"id":"fdc65a7e1a47d145","repo":"tursodatabase/turso","slug":"remote-close-returned-unexpected-response-type-r","errorCode":null,"errorMessage":"Remote close returned unexpected response type: {result.Response?.Type}","messagePattern":"Remote close returned unexpected response type: (.+?)","errorType":"exception","errorClass":"TursoException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoRemoteClient.cs","lineNumber":330,"sourceCode":"        for (var i = 0; i < batch.StepResults.Count; i++)\n        {\n            var stepResult = batch.StepResults[i]\n                             ?? throw new TursoException($\"Remote batch did not return a result for step {i}.\");\n            statementResults.Add(stepResult);\n        }\n\n        return statementResults;\n    }\n\n    private static void ValidateCloseResult(RemotePipelineResponse response)\n    {\n        foreach (var result in response.Results)\n        {\n            switch (result.Type)\n            {\n                case \"ok\":\n                    if (result.Response?.Type is not \"close\")\n                        throw new TursoException($\"Remote close returned unexpected response type: {result.Response?.Type}\");\n                    break;\n\n                case \"error\":\n                    throw CreateRemoteError(result.Error);\n\n                default:\n                    throw new TursoException($\"Remote close returned unexpected result type: {result.Type}\");\n            }\n        }\n    }\n\n    private static TursoException CreateRemoteError(RemoteError? error)\n    {\n        if (error is null)\n            return new TursoRemoteSqlException(\"Remote SQL execution failed.\");\n\n        return string.IsNullOrWhiteSpace(error.Code)\n            ? new TursoRemoteSqlException($\"Remote SQL execution failed: {error.Message}\")","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/dotnet/src/Turso.Data/TursoRemoteClient.cs#L312-L348","documentation":"During connection close, every result entry in the pipeline response must be an ok whose inner response type is \"close\". ValidateCloseResult threw because an ok entry carried a different inner response type, so the reply does not acknowledge the close request that was sent.","triggerScenarios":"Closing or disposing a remote TursoConnection that has an open session (a baton): CloseAsync posts a close request and the server's ok entry has response.type != \"close\". This can surface from 'await using var conn = ...' disposal, which surprises developers because the exception fires at Dispose time.","commonSituations":"Server version drift in close semantics; sessions already invalidated server side (idle expiry) answered with a different payload; gateways rewriting responses; custom servers that skip close acknowledgment.","solutions":["Check whether the exception occurs during CloseAsync/Dispose and whether the session had been idle long enough to expire server side.","Align server and Turso.Data binding versions.","If sessions expire quickly, lower idle time between requests or reopen connections per unit of work so close happens on a live session.","Remove response-rewriting intermediaries.","Report with the raw envelope if current versions still send a non-close ack."],"exampleFix":"// before -- a close failure during disposal can mask the real work result\nawait using var conn = new TursoConnection(cs);\nawait conn.OpenAsync();\nawait DoWorkAsync(conn); // exception at Dispose if close ack is malformed\n\n// after -- separate work from close so close failures are visible and non-fatal\nvar conn = new TursoConnection(cs);\ntry\n{\n    await conn.OpenAsync();\n    await DoWorkAsync(conn);\n}\nfinally\n{\n    try { await conn.CloseAsync(); }\n    catch (TursoException ex) { logger.LogWarning(ex, \"Session close failed; server will reap it\"); }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await conn.CloseAsync(); }\ncatch (TursoException ex) when (ex.Message.Contains(\"Remote close\"))\n{\n    // the work already committed; a malformed close ack is a server/protocol issue\n    logger.LogWarning(ex, \"Session close ack malformed; server will reap the session\");\n}","preventionTips":["Do not rely on 'await using' disposal as the only close path -- wrap CloseAsync explicitly so close failures cannot mask successful work.","Keep connections short-lived or keep them active; long-idle sessions invite server-side expiry and odd close replies.","Version-align server and bindings.","Take JSON-rewriting intermediaries off the pipeline route."],"tags":["turso","dotnet","remote","connection-close","protocol"],"backgroundTag":"unexpected-response-type","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}