gastownhall/beads · error
not found
Error message
not found
What it means
publicCreateValidationError is the internal wrapper that tags every deterministic public-create refusal with storage.ErrValidation: fmt.Errorf("%w: %w", storage.ErrValidation, err). Callers use errors.Is(err, storage.ErrValidation) to distinguish caller mistakes (bad input, invalid relationships) from infrastructure failures, which are passed through unclassified.
Source
Thrown at cmd/bd/state.go:45
// to choose — Reader.Get's issue-then-wisp lookup finds an ephemeral row on its
// own, which is how the DIRECT route acquires wisp support it never had: it
// used to call store.GetLabels, which only ever reads the durable table.
//
// Resolution stays a front-door job, and stays shared with `bd label`:
// GetRequest.ID is exact by contract, so the partial-id affordance the direct
// route offers cannot live below this line.
func resolveStateTarget(ctx context.Context, issueID string) (*issueops.IssueDetails, error) {
fullID, err := resolveLabelTarget(ctx, issueID)
if err != nil {
return nil, err
}
reader, err := openIssueReader()
if err != nil {
return nil, err
}
details, err := reader.Get(ctx, issueops.GetRequest{ID: fullID})
if errors.Is(err, storage.ErrNotFound) {
return nil, errors.New("not found")
}
if err != nil {
return nil, err
}
return details, nil
}
var stateCmd = &cobra.Command{
Use: "state <issue-id> <dimension>",
GroupID: "issues",
Short: "Query the current value of a state dimension",
Long: `Query the current value of a state dimension from an issue's labels.
State labels follow the convention <dimension>:<value>, for example:
patrol:active
mode:degraded
health:healthy
View on GitHub (pinned to 71377f2769)
Solutions
- Use errors.Is(err, storage.ErrValidation) to detect this class; then inspect the wrapped cause with errors.As/Unwrap for specifics.
- Fix the request field the wrapped error names (ID length, dependency type, duplicate edge, etc.).
- Do not retry: this is a deterministic input problem, not transient.
Example fix
// before
if err := store.ExecuteCreate(ctx, req); err != nil { log.Fatal(err) }
// after
if err := store.ExecuteCreate(ctx, req); err != nil {
if errors.Is(err, storage.ErrValidation) { return fmt.Errorf("invalid create request: %w", err) }
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
if err := ValidatePublicCreateRequest(req); err != nil { return err } // pre-validate with the exported helper Type guard
func isValidationErr(err error) bool { return errors.Is(err, storage.ErrValidation) } Try / catch
err := store.ExecuteCreate(ctx, req)
switch {
case errors.Is(err, storage.ErrValidation):
// deterministic input refusal; inspect wrapped cause
case err != nil:
// infrastructure/commit error; safe to retry/log
} Prevention
- Run ValidatePublicCreateRequest before ExecuteCreate.
- Treat ErrValidation as non-retryable and surface to the caller.
- Use errors.Unwrap loop / errors.As to extract the specific cause.
When it happens
Trigger: Any validation failure in ValidatePublicCreateRequest, PreparePublicCreateRequest, validatePublicCreateDependencies, or the deterministic-refusal branches of ClassifyPublicCreateError; the wrap happens at public_create.go:121.
Common situations: API consumers checking error types see ErrValidation unexpectedly when they sent malformed create requests; test authors asserting on error identity chain.
Related errors
- no store is open for this workspace
- db: ChildCounterSQLRepository.NextChildID: parentID must not
- db: DependencySQLRepository.Insert: dep must not be nil
- db: DependencySQLRepository.Insert: IssueID must not be empt
- db: DependencySQLRepository.Insert: DependsOnID must not be
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/176f1132a4c243cf.
Report an issue: GitHub.