gastownhall/beads · error

invalid fromRef: %w

Error message

invalid fromRef: %w

What it means

DiffInTx validates both refs with ValidateRef before interpolating them into a dolt_diff() table-function call; this error is raised when fromRef fails validation. The library rejects refs containing SQL metacharacters or invalid forms because dolt_diff requires literal ref names. It is a caller-input error, not a database failure.

Source

Thrown at internal/storage/issueops/diff.go:18

package issueops

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)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped ValidateRef error to see which rule the ref violated
  2. Use plain branch/tag/commit names without quotes or special characters as fromRef
  3. Validate user-supplied refs at your CLI boundary before calling DiffInTx
  4. Pre-check with ValidateRef yourself to fail fast with a clearer message

Example fix

// before
DiffInTx(ctx, tx, "main'; --", "feature")
// after
from := "main" // plain, validated ref
if err := issueops.ValidateRef(from); err != nil {
    return fmt.Errorf("bad from ref %q: %w", from, err)
}
DiffInTx(ctx, tx, from, "feature")
Defensive patterns

Strategy: validation

Validate before calling

func validRef(ref string) bool {
    if ref == "" || len(ref) > 200 {
        return false
    }
    for _, r := range ref {
        if !('a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' || '0' <= r && r <= '9' ||
            r == '-' || r == '_' || r == '.' || r == '/') {
            return false
        }
    }
    return true
}
// call ValidateRef(from) yourself before DiffInTx to fail fast

Try / catch

if err := DiffInTx(ctx, tx, from, to); err != nil {
    if strings.Contains(err.Error(), "invalid fromRef") {
        return fmt.Errorf("usage: from must be a plain branch/tag/commit name, got %q", from)
    }
    return err
}

Prevention

When it happens

Trigger: Calling DiffInTx with a fromRef that is empty, contains quotes/semicolons, or otherwise fails ValidateRef (e.g. "main'; DROP TABLE issues--", a ref with illegal characters, or a non-ref string).

Common situations: Passing raw branch names containing shell-style characters; building refs from untrusted CLI input; typos like trailing slashes or spaces; passing a refspec form the validator rejects.

Related errors


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