gastownhall/beads · error

partition wisp ids: %w

Error message

partition wisp ids: %w

What it means

PartitionWispIDsInTx batches IDs into `SELECT id FROM wisps WHERE id IN (...)` queries. This error wraps a query execution failure that is not a table-not-exist error (that case is deliberately tolerated and treated as 'no wisps'). It indicates a real failure opening the rows: connection failure, SQL error, timeout, or permission problem.

Source

Thrown at internal/storage/issueops/wisp_routing.go:164

			end = len(ids)
		}
		batch := ids[start:end]
		placeholders := make([]string, len(batch))
		args := make([]any, len(batch))
		for i, id := range batch {
			placeholders[i] = "?"
			args[i] = id
		}
		//nolint:gosec // G201: only ? placeholders in the IN clause.
		rows, qErr := tx.QueryContext(ctx,
			fmt.Sprintf("SELECT id FROM wisps WHERE id IN (%s)", strings.Join(placeholders, ",")),
			args...)
		if qErr != nil {
			// Wisps table may not exist yet on older schemas — treat as "no wisps".
			if isTableNotExistError(qErr) {
				return nil, append([]string(nil), ids...), nil
			}
			return nil, nil, fmt.Errorf("partition wisp ids: %w", qErr)
		}
		for rows.Next() {
			var id string
			if scanErr := rows.Scan(&id); scanErr != nil {
				_ = rows.Close()
				return nil, nil, fmt.Errorf("partition wisp ids: scan: %w", scanErr)
			}
			wispSet[id] = struct{}{}
		}
		_ = rows.Close()
		if rowsErr := rows.Err(); rowsErr != nil {
			return nil, nil, fmt.Errorf("partition wisp ids: rows: %w", rowsErr)
		}
	}

	for _, id := range ids {
		if _, ok := wispSet[id]; ok {
			wispIDs = append(wispIDs, id)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap the driver error to identify the root cause (timeout, connection reset, permission)
  2. Retry with a fresh transaction — the operation is read-only and idempotent
  3. Reduce the number of IDs per call (or the batch size) so each chunk finishes within the deadline
  4. Verify DB permissions and connectivity; check Dolt server logs for the corresponding failure
Defensive patterns

Strategy: retry

Validate before calling

if err := ctx.Err(); err != nil { return err } // fail fast before query
if len(ids) == 0 { return nil }

Try / catch

wispIDs, permIDs, err := issueops.PartitionWispIDsInTx(ctx, tx, ids)
if err != nil {
	if errors.Is(err, context.DeadlineExceeded) {
		// chunk ids smaller and retry
	}
	return err
}

Prevention

When it happens

Trigger: Calling PartitionWispIDsInTx (directly or through any of its six wrappers) when the batched IN-query against wisps fails with a driver/SQL error other than 'table does not exist' — e.g. connection reset, context deadline exceeded mid-query, or an SQL syntax/permission error.

Common situations: Remote Dolt connection dropped during bulk hydration of many issue IDs; context timeout hit because the batch was too large for the WAN link; mis-provisioned DB credentials revoked mid-session.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/a4e35631126e9bbb. Report an issue: GitHub.