tursodatabase/turso · error · TursoServerlessException

Describe execution failed

Error message

Describe execution failed

What it means

PrepareAsync sends a Hrana pipeline containing a describe request. If the first pipeline result comes back with type "error", the client wraps it in TursoServerlessException using the server's message — and this literal text only when the server error carried no message at all. The underlying cause is almost always the SQL itself failing to describe.

Source

Thrown at bindings/dotnet/src/Turso.Serverless.Client/TursoSession.cs:54

    internal async Task<TursoStatementDescription> DescribeAsync(string sql, TimeSpan? queryTimeout, CancellationToken cancellationToken)
    {
        var request = new HranaPipelineRequest
        {
            Baton = _baton,
            Requests =
            [
                new HranaPipelineRequestItem { Type = "describe", Sql = sql },
                new HranaPipelineRequestItem { Type = "get_autocommit" },
            ],
        };

        var response = await RunPipelineAsync(request, queryTimeout, cancellationToken).ConfigureAwait(false);

        if (response.Results is [var result, ..])
        {
            if (result.Type == "error")
            {
                throw new TursoServerlessException(result.Error?.Message ?? "Describe execution failed", result.Error?.Code);
            }

            if (result.Response is { Type: "describe", Result: { } resultElement })
            {
                var describe = resultElement.Deserialize<HranaDescribeResult>(new JsonSerializerOptions(JsonSerializerDefaults.Web));
                if (describe is not null)
                {
                    return new TursoStatementDescription(
                        parameterNames: describe.Params?.Select(static p => p.Name ?? "").ToArray() ?? [],
                        columns: describe.Cols?.Select(static c => c.Name ?? "").ToArray() ?? [],
                        columnTypes: describe.Cols?.Select(static c => c.Decltype ?? "").ToArray() ?? [],
                        isExplain: describe.IsExplain,
                        isReadonly: describe.IsReadonly);
                }
            }
        }

        throw new TursoServerlessException("Unexpected describe response");

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Run the same statement in the turso CLI (turso db shell) against the same database to get the full server error
  2. Check that every table/column referenced exists on the target database, not just locally
  3. If the message is the generic fallback, log the full response body and update the client so the server message propagates
  4. For dynamic SQL, validate table/column names against the schema before preparing

Example fix

// before
var desc = await session.PrepareAsync($"SELECT {userColumn} FROM {userTable}");

// after
// verify identifiers exist first
var tables = await session.ExecuteAsync("SELECT name FROM sqlite_master WHERE type='table'");
var desc = await session.PrepareAsync($"SELECT {userColumn} FROM {userTable}");
Defensive patterns

Strategy: try-catch

Try / catch

try { var desc = await session.PrepareAsync(sql, ct); } catch (TursoServerlessException ex) { log.Error($"prepare failed [{ex.Code}]: {ex.Message}; sql={sql}"); throw; }

Prevention

When it happens

Trigger: Preparing a statement with a syntax error, an unknown table/column, or a malformed statement: session.PrepareAsync("SELCT 1") or a query referencing a table that does not exist in the target database.

Common situations: Schema drift between local and remote databases; migrations not applied to the Turso database being addressed; typos in dynamically-built SQL strings.

Related errors


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