tursodatabase/turso · error · TursoException

Unable to parse remote {Type} response: {ex.Message}

Error message

Unable to parse remote {Type} response: {ex.Message}

What it means

The inner result payload of an execute or batch response did not match the expected CLR shape: deserializing it into RemoteStatementResult or RemoteBatchResult raised a JsonException, rethrown with the parser's message and the response type. Typical causes are field type changes -- cols/rows not being arrays, affected_row_count not numeric, or a last_insert_rowid shape the bindings cannot map.

Source

Thrown at bindings/dotnet/src/Turso.Data/TursoRemoteClient.cs:559

    [JsonPropertyName("type")]
    public string Type { get; init; } = "";

    [JsonPropertyName("result")]
    public JsonElement Result { get; init; }

    public T DeserializeResult<T>()
    {
        if (Result.ValueKind is JsonValueKind.Undefined or JsonValueKind.Null)
            throw new TursoException($"Remote response {Type} did not include a result.");

        try
        {
            return Result.Deserialize<T>()
                   ?? throw new TursoException($"Remote response {Type} returned an empty result.");
        }
        catch (JsonException ex)
        {
            throw new TursoException($"Unable to parse remote {Type} response: {ex.Message}");
        }
    }
}

internal sealed class RemoteError
{
    [JsonPropertyName("message")]
    public string Message { get; init; } = "";

    [JsonPropertyName("code")]
    public string? Code { get; init; }
}

internal sealed class TursoRemoteSqlException(string message) : TursoException(message);

internal sealed class RemoteBatchResult
{
    [JsonPropertyName("step_results")]

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Read the parser message embedded in the exception -- it names the JSON path and the expected type, which pinpoints the offending field.
  2. Capture the raw envelope and compare the failing field with what the bindings expect.
  3. Align server and Turso.Data package versions; result-schema changes track releases.
  4. Test against a stock instance to rule out a custom server.
  5. Report the raw payload if both sides are current.
Defensive patterns

Strategy: try-catch

Try / catch

try { return await cmd.ExecuteReaderAsync(cancellationToken); }
catch (TursoException ex) when (ex.Message.StartsWith("Unable to parse remote "))
{
    // parser message names the offending JSON path -- log it verbatim
    logger.LogError(ex, "Result schema mismatch for {Sql}", cmd.CommandText);
    throw;
}

Prevention

When it happens

Trigger: Remote command or batch execution where the "result" JSON exists but its fields violate the expected schema, for example rows entries that are objects instead of arrays, or a string where a number is required.

Common situations: Server newer or older than the bindings with schema drift in the result payload; custom /v2/pipeline implementations; middleware mangling nested types; preview server features emitting extra/renamed fields.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/22bbdc4840f2651e. Report an issue: GitHub.