gastownhall/beads · error

get next child ID: query existing children: %w

Error message

get next child ID: query existing children: %w

What it means

GetNextChildIDTx queries all existing child IDs of a parent (id LIKE 'parent.%') to recover the true max child number, and wraps query execution failures with "get next child ID: query existing children: %w". This guards against a stale or missing counter row. The error means the SELECT on the issues table failed before any rows were read.

Source

Thrown at internal/storage/issueops/child_id.go:33

	var lastChild int
	//nolint:gosec // G201: counterTable is one of two hardcoded constants.
	err := tx.QueryRowContext(ctx,
		fmt.Sprintf("SELECT last_child FROM %s WHERE parent_id = ?", counterTable),
		parentID).Scan(&lastChild)
	if err == sql.ErrNoRows {
		lastChild = 0
	} else if err != nil {
		return "", fmt.Errorf("get next child ID: read counter: %w", err)
	}

	//nolint:gosec // G201: issueTable is one of two hardcoded constants.
	rows, err := tx.QueryContext(ctx, fmt.Sprintf(`
		SELECT id FROM %s
		WHERE id LIKE CONCAT(?, '.%%')
		  AND id NOT LIKE CONCAT(?, '.%%.%%')
	`, issueTable), parentID, parentID)
	if err != nil {
		return "", fmt.Errorf("get next child ID: query existing children: %w", err)
	}
	defer rows.Close()

	for rows.Next() {
		var id string
		if err := rows.Scan(&id); err != nil {
			return "", fmt.Errorf("get next child ID: scan child row: %w", err)
		}
		_, childNum, ok := ParseHierarchicalID(id)
		if ok && childNum > lastChild {
			lastChild = childNum
		}
	}
	if err := rows.Err(); err != nil {
		return "", fmt.Errorf("get next child ID: iterate children: %w", err)
	}

	nextChild := lastChild + 1

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the transaction if the wrapped error indicates a connection or lock-wait failure.
  2. Verify the database schema is current (issues table and counter table both present).
  3. Roll back the transaction on this error rather than continuing; the tx is unusable after failure.
  4. Check context deadlines if bulk operations are timing out.
Defensive patterns

Strategy: retry

Validate before calling

if ctx.Err() != nil { return ctx.Err() }

Try / catch

if err != nil {
    tx.Rollback()
    if isTransient(err) { return retry(err) }
    return fmt.Errorf("child lookup failed: %w", err)
}

Prevention

When it happens

Trigger: Calling ExecuteCreate when: the LIKE query against the issues table fails from a missing/corrupted table, the transaction is aborted, the context is cancelled, or the connection is lost.

Common situations: Sub-issue creation against a DB missing the issues table (bad routing/table constants), aborted transaction reuse after an earlier failed statement, cancellation during bulk child creation, remote Dolt connectivity loss.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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