gastownhall/beads · error

db: CountForPrefix: prefix must not be empty

Error message

db: CountForPrefix: prefix must not be empty

What it means

CountForPrefix() counts issues whose ids share a given prefix; a blank prefix has no meaning and would match nothing or everything depending on the LIKE pattern, so the repository rejects it explicitly. It is an input-validation guard before the COUNT query.

Source

Thrown at internal/storage/domain/db/issue.go:623

		return false, errors.New("db: Exists: id must not be empty")
	}
	table := pickIssueTable(opts.UseWispsTable)
	//nolint:gosec // G201: table is one of two hardcoded constants
	row := r.runner.QueryRowContext(ctx, fmt.Sprintf("SELECT 1 FROM %s WHERE id = ? LIMIT 1", table), id)
	var one int
	err := row.Scan(&one)
	if errors.Is(err, sql.ErrNoRows) {
		return false, nil
	}
	if err != nil {
		return false, fmt.Errorf("db: Exists %s: %w", id, err)
	}
	return true, nil
}

func (r *issueSQLRepositoryImpl) CountForPrefix(ctx context.Context, prefix string, opts domain.IssueTableOpts) (int, error) {
	if prefix == "" {
		return 0, errors.New("db: CountForPrefix: prefix must not be empty")
	}
	table := pickIssueTable(opts.UseWispsTable)
	var count int
	//nolint:gosec // G201: table is one of two hardcoded constants
	err := r.runner.QueryRowContext(ctx, fmt.Sprintf(`
		SELECT COUNT(*)
		FROM %s
		WHERE id LIKE CONCAT(?, '-%%')
		  AND INSTR(SUBSTRING(id, LENGTH(?) + 2), '.') = 0
	`, table), prefix, prefix).Scan(&count)
	if err != nil {
		return 0, fmt.Errorf("db: CountForPrefix %s: %w", prefix, err)
	}
	return count, nil
}

func (r *issueSQLRepositoryImpl) NextCounterID(ctx context.Context, prefix string) (int, error) {
	if prefix == "" {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Supply a non-empty prefix (e.g. "bd") before calling
  2. If empty prefix is a valid 'count all' intent, call a list-all/count-all API instead
  3. Log/validate configuration at startup so empty prefixes fail early

Example fix

// before
n, err := repo.CountForPrefix(ctx, cfg.IDPrefix, opts)
// after
if cfg.IDPrefix == "" {
    return errors.New("id prefix not configured")
}
n, err := repo.CountForPrefix(ctx, cfg.IDPrefix, opts)
Defensive patterns

Strategy: validation

Validate before calling

if prefix == "" {
    return errors.New("prefix must be configured before counting issues")
}

Type guard

func validPrefix(p string) bool { return strings.TrimSpace(p) != "" }

Try / catch

n, err := repo.CountForPrefix(ctx, prefix, opts)
if err != nil {
    return fmt.Errorf("count prefix %q: %w", prefix, err)
}

Prevention

When it happens

Trigger: Calling issueSQLRepositoryImpl.CountForPrefix(ctx, "", opts) — e.g. a prefix derived from config, CLI flag, or an issue-ID parse that came back empty.

Common situations: Missing or empty --prefix style configuration; computing a prefix from a partially parsed ID; a metadata.json field left blank.

Related errors


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