gastownhall/beads · error
invalid toRef: %w
Error message
invalid toRef: %w
What it means
Identical guard to the fromRef case but for the toRef argument of DiffInTx: ValidateRef rejected the destination ref before it can be interpolated into dolt_diff(). The library fails fast to keep the dolt_diff query injection-safe. It is a caller-input error.
Source
Thrown at internal/storage/issueops/diff.go:21
import (
"context"
"database/sql"
"fmt"
"github.com/steveyegge/beads/internal/storage"
"github.com/steveyegge/beads/internal/types"
)
// DiffInTx returns changes between two commits or branches by querying
// Dolt's dolt_diff() table function.
//
// nolint:gosec // G201: refs are validated by ValidateRef() - dolt_diff requires literal refs
func DiffInTx(ctx context.Context, tx *sql.Tx, fromRef, toRef string) ([]*storage.DiffEntry, error) {
if err := ValidateRef(fromRef); err != nil {
return nil, fmt.Errorf("invalid fromRef: %w", err)
}
if err := ValidateRef(toRef); err != nil {
return nil, fmt.Errorf("invalid toRef: %w", err)
}
query := fmt.Sprintf(`
SELECT
COALESCE(from_id, '') as from_id,
COALESCE(to_id, '') as to_id,
diff_type,
from_title, to_title,
from_description, to_description,
from_status, to_status,
from_priority, to_priority
FROM dolt_diff('%s', '%s', 'issues')
`, fromRef, toRef)
rows, err := tx.QueryContext(ctx, query)
if err != nil {
return nil, fmt.Errorf("failed to get diff: %w", err)
}View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped ValidateRef error for the specific rule violated
- Pass plain single refs (branch, tag, or commit hash) as toRef — not ranges or expressions
- Pre-validate with ValidateRef at the caller boundary
- Strip or reject whitespace and SQL metacharacters from user input
Example fix
// before DiffInTx(ctx, tx, "main", "dev..HEAD") // after DiffInTx(ctx, tx, "main", "HEAD") // one plain ref per argument; ranges are not refs
Defensive patterns
Strategy: validation
Validate before calling
func validRef(ref string) bool {
if ref == "" || strings.ContainsAny(ref, "'\"; --") || strings.Contains(ref, "..") {
return false
}
return issueops.ValidateRef(ref) == nil
}
// reject ranges like "main..dev"; pass two refs instead Try / catch
if err := DiffInTx(ctx, tx, from, to); err != nil {
if strings.Contains(err.Error(), "invalid toRef") {
return fmt.Errorf("usage: to must be a single plain ref, got %q", to)
}
return err
} Prevention
- Reject range expressions ("a..b") — split them into two refs before calling
- Trim and sanitize target-branch input from users and CI variables
- Use the library's ValidateRef as the single source of truth
- Document accepted ref forms in your command help
When it happens
Trigger: Calling DiffInTx with an invalid toRef: empty string, embedded quotes/semicolons, illegal characters, or a malformed ref form rejected by ValidateRef.
Common situations: User-supplied target branch containing unexpected characters; passing a range string like "main..dev" instead of two separate refs; automated pipelines propagating unsanitized ref names.
Related errors
- invalid fromRef: %w
- ErrFieldTooLong
- title is required
- invalid identifier: %q
- close: id must not be empty
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/908507b53b7dd868.
Report an issue: GitHub.