gastownhall/beads · error · issueops.ErrValidation
%w: bootstrap requires a non-empty issue prefix
Error message
%w: bootstrap requires a non-empty issue prefix
What it means
ValidateBootstrapRequest wraps issueops.ErrValidation when the bootstrap request's issue prefix is empty after normalization. Bootstrap mints issues under a prefix, so an empty prefix would create unnameable issues; the validator runs before any transaction opens, guaranteeing "a refusal writes nothing".
Source
Thrown at internal/workapi/bootstrap.go:53
//
// The settings plane strips a trailing hyphen from this key. Doing it here
// instead of relying on that means BootstrapResult.Prefix and the value a later
// VerifyIdentity answers with are one value on every backend, including the
// unit-of-work one whose write does not pass through that plane's normalizer.
func NormalizeBootstrapPrefix(prefix string) string {
return strings.TrimRight(prefix, "-")
}
// ValidateBootstrapRequest refuses a bootstrap that cannot produce a usable
// workspace and returns the request as it will be WRITTEN.
//
// Every implementation validates through it BEFORE opening a transaction, which
// is what makes issueops.Bootstrapper's "a refusal writes nothing" true of the
// connection as well as of the keys.
func ValidateBootstrapRequest(req issueops.BootstrapRequest) (issueops.BootstrapRequest, error) {
req.Prefix = NormalizeBootstrapPrefix(req.Prefix)
if req.Prefix == "" {
return issueops.BootstrapRequest{}, fmt.Errorf("%w: bootstrap requires a non-empty issue prefix", issueops.ErrValidation)
}
if req.ProjectID == "" {
return issueops.BootstrapRequest{}, fmt.Errorf("%w: bootstrap requires a project id; this role does not mint one", issueops.ErrValidation)
}
return req, nil
}
// RefuseIdentifiedSubstrate turns the pair a bootstrap read into the refusal
// issueops.Bootstrapper promises, or nil when the substrate is free.
//
// EITHER MARKER IS ENOUGH. A substrate several rigs share carries a prefix one
// of them chose, and a bootstrap that overwrote it would rename every id the
// others are about to mint; a substrate carrying only a project id is either a
// server-provisioned one bd must adopt rather than stamp, or a bootstrap that
// failed partway, and bd cannot tell those apart. The error carries both values
// so its caller can.
func RefuseIdentifiedSubstrate(prefix, projectID string) error {
if prefix == "" && projectID == "" {View on GitHub (pinned to 71377f2769)
Solutions
- Set a non-empty prefix on the BootstrapRequest, e.g. Prefix: "bd"
- Check the config/env source feeding Prefix for empty or hyphen-only values
- Check errors.Is(err, issueops.ErrValidation) to distinguish this refusal from backend failures
Example fix
// before
req := issueops.BootstrapRequest{Prefix: cfg.IssuePrefix, ProjectID: cfg.ProjectID}
// after
if strings.Trim(cfg.IssuePrefix, "-") == "" { return fmt.Errorf("config issuePrefix must be non-empty") }
req := issueops.BootstrapRequest{Prefix: cfg.IssuePrefix, ProjectID: cfg.ProjectID} Defensive patterns
Strategy: validation
Validate before calling
if strings.Trim(req.Prefix, "-") == "" {
return fmt.Errorf("bootstrap prefix must be set (got %q)", req.Prefix)
} Try / catch
normalized, err := workapi.ValidateBootstrapRequest(req)
if errors.Is(err, issueops.ErrValidation) {
return fmt.Errorf("config bootstrap error: %w", err)
} Prevention
- Load prefix from a single validated config source
- Fail fast at startup if prefix config is empty
- Trim hyphens yourself before submitting to match normalization
When it happens
Trigger: Calling any issueops Bootstrapper implementation with BootstrapRequest{Prefix: ""} (or a prefix that normalizes to empty, e.g. only a hyphen "-").
Common situations: Config file missing the prefix key; environment variable interpolation producing an empty string; YAML value set to just "-" which NormalizeBootstrapPrefix strips.
Related errors
- %w: bootstrap requires a project id; this role does not mint
- invalid database name %q (use cfg.GetDoltDatabase() to resol
- %w: issue ID %s does not match configured prefix %s
- prefix mismatch: database uses '%s' (allowed: %s) but you sp
- prefix mismatch: database uses '%s' but you specified '%s' (
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/88f383fb7cb2c08c.
Report an issue: GitHub.