tursodatabase/turso · error · DatabaseError

batch response does not have one result and one error per st

Error message

batch response does not have one result and one error per step

What it means

The batch protocol guarantees one result slot and one error slot per submitted step. When the returned step_results/step_errors arrays are missing, not arrays, or differ in length from the number of steps, the client cannot map results back to statements and throws.

Source

Thrown at serverless/javascript/src/session.ts:633

    if (!first) {
      throw new DatabaseError('missing batch result in pipeline response');
    }
    if (first.type === 'error') {
      throw new DatabaseError(first.error?.message || 'Batch execution failed', first.error?.code);
    }
    if (first.response?.type !== 'batch') {
      throw new DatabaseError(`expected batch result in pipeline response, got ${first.response?.type}`);
    }
    const batchResult = first.response.result as BatchResultData | undefined;
    const stepResults = batchResult?.step_results;
    const stepErrors = batchResult?.step_errors;
    if (
      !Array.isArray(stepResults) ||
      !Array.isArray(stepErrors) ||
      stepResults.length !== steps.length ||
      stepErrors.length !== steps.length
    ) {
      throw new DatabaseError('batch response does not have one result and one error per step');
    }

    // One result per user statement, in input order; null for statements
    // that did not complete.
    const results: Array<any | null> = statements.map((_, i) => {
      const stepResult = stepResults[firstUserStepIdx + i];
      return stepResult ? this.decodeBatchStepResult(stepResult, safeIntegers, raw) : null;
    });

    // Surface the failing step: BEGIN first, then the user statements
    // (with their index), then COMMIT.
    const rollbackError = rollbackIdx >= 0 ? stepErrors[rollbackIdx] : null;
    const throwStepError = (error: { message?: string; code?: string } | null, batchIndex?: number): never => {
      const e = new DatabaseError(error?.message || 'Batch execution failed', error?.code);
      if (batchIndex !== undefined) {
        e.batchIndex = batchIndex;
      }
      e.batchResults = results;

View on GitHub (pinned to c1e5928725)

Solutions

  1. Retry the batch to rule out a transient truncation.
  2. Split very large batches into smaller ones to reduce response size.
  3. Verify client and server versions match.
  4. Inspect the raw response JSON to confirm what the server sent before filing a bug.
Defensive patterns

Strategy: retry

Validate before calling

null

Try / catch

try { await session.batch(stmts); } catch (e) { if (e instanceof DatabaseError && e.message.includes('one result and one error per step')) { /* retry with backoff; reduce batch size if large */ } else throw e; }

Prevention

When it happens

Trigger: session.batch() with N steps where the server's BatchResultData has step_results/step_errors arrays of length != N, or non-array values — server bug, truncated response, or partial pipeline execution.

Common situations: Server under load returning partial pipeline data, network middleboxes truncating large batch responses, protocol drift between client and server versions.

Related errors


AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31). Data as JSON: /api/errors/ec5608e826012a8d. Report an issue: GitHub.