gastownhall/beads · warning

journal: close derived is_blocked from %s: %w

Error message

journal: close derived is_blocked from %s: %w

What it means

rows.Close() returned an error after completing the is_blocked snapshot query. Rare; indicates the driver could not cleanly release the result set, which can leave the connection in a bad state, so the transaction fails fast.

Source

Thrown at internal/storage/issueops/journal.go:249

					break
				}
				return nil, fmt.Errorf("journal: snapshot derived is_blocked from %s: %w", target.table, err)
			}
			for rows.Next() {
				var id string
				var blocked int
				if err := rows.Scan(&id, &blocked); err != nil {
					_ = rows.Close()
					return nil, fmt.Errorf("journal: scan derived is_blocked from %s: %w", target.table, err)
				}
				snapshot[blockedJournalKey{table: target.table, id: id}] = blocked != 0
			}
			if err := rows.Err(); err != nil {
				_ = rows.Close()
				return nil, fmt.Errorf("journal: iterate derived is_blocked from %s: %w", target.table, err)
			}
			if err := rows.Close(); err != nil {
				return nil, fmt.Errorf("journal: close derived is_blocked from %s: %w", target.table, err)
			}
		}
	}
	return snapshot, nil
}

// recordBlockedJournalChanges compares the stable post-maintenance state with
// the captured state and journals only beads whose derived is_blocked value
// actually changed. The emitted update carries the complete post-mutation
// snapshot, allowing a cursor consumer to stay correct without graph queries.
func recordBlockedJournalChanges(
	ctx context.Context,
	tx DBTX,
	before blockedJournalSnapshot,
	issueIDs, wispIDs []string,
) error {
	if before == nil {
		return nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped error; it usually masks an earlier connection problem
  2. Retry the transaction on a fresh connection
  3. Check connection-pool health (max lifetime, stale connections)
  4. Upgrade the SQL driver if close errors recur

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

if err := db.Ping(); err != nil { /* refresh pool before the transaction */ }

Type guard

null

Try / catch

snap, err := captureBlockedJournalSnapshot(ctx, tx)
if err != nil {
  if isCloseErr(err) { tx.Rollback(); return retryWithFreshTx(ctx) }
  return err
}

Prevention

When it happens

Trigger: The deferred-style explicit rows.Close() after rows.Err() returned non-nil, typically due to an already-broken connection or driver-level cleanup failure.

Common situations: Connection invalidated mid-query; driver-specific close failures under contention or timeouts.

Related errors


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