gastownhall/beads · error
%w: add comment requires an issue ID
Error message
%w: add comment requires an issue ID
What it means
ValidateAddCommentRequest rejects an AddCommentRequest with an empty IssueID. A comment must anchor to an existing issue or wisp row; with no ID there is nothing to attach to, so the request fails validation with wrapped storage.ErrValidation before any query runs.
Source
Thrown at internal/storage/issueops/commenter.go:25
"strings"
"github.com/steveyegge/beads/internal/storage"
publicops "github.com/steveyegge/beads/issueops"
)
// ValidateAddCommentRequest applies the request rules every Commenter
// implementation shares.
//
// Blankness is decided on a TRIMMED copy and the request's own Text is left
// alone: a comment of nothing but whitespace carries no information and is
// almost always a shell quoting accident, but a comment that merely begins
// with a newline is a comment.
func ValidateAddCommentRequest(request publicops.AddCommentRequest) error {
if request.Author == "" {
return fmt.Errorf("%w: add comment requires an author", storage.ErrValidation)
}
if request.IssueID == "" {
return fmt.Errorf("%w: add comment requires an issue ID", storage.ErrValidation)
}
if strings.TrimSpace(request.Text) == "" {
return fmt.Errorf("%w: comment text cannot be empty", storage.ErrValidation)
}
return nil
}
// AddCommentCommitMessage is the history entry a comment records. It is the
// spelling both stores' own AddIssueComment already wrote.
func AddCommentCommitMessage(issueID string) string {
return "bd: comment " + issueID
}
// ExecuteAddComment appends one comment in tx and reports the durable tables
// changed. It is the store-backed body behind the Commenter accessor; the
// unit-of-work provider has its own, for the reason Lifecycle does.
//
// A comment on an ephemeral row changes only wisp_comments, whichView on GitHub (pinned to 71377f2769)
Solutions
- Populate request.IssueID with the target issue's ID before calling AddComment.
- Validate the ID is non-empty (and well-formed, e.g. has a prefix) at the call site and report which input was missing.
- Classify with errors.Is(err, storage.ErrValidation) and reject the request upstream instead of retrying.
Example fix
// before
req := publicops.AddCommentRequest{Author: author, Text: text}
_ = store.AddComment(ctx, req) // fails: no issue ID
// after
if issueID == "" {
return fmt.Errorf("usage: bd comment <issue-id> <text>")
}
req := publicops.AddCommentRequest{IssueID: issueID, Author: author, Text: text}
if err := store.AddComment(ctx, req); err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
if req.IssueID == "" {
return errors.New("issue ID is required to add a comment")
} Try / catch
if err := store.AddComment(ctx, req); err != nil {
if errors.Is(err, storage.ErrValidation) {
return fmt.Errorf("invalid request (issue ID?): %w", err)
}
return err
} Prevention
- Validate CLI/args-derived issue IDs are non-empty before building the request.
- Use a helper that refuses to build AddCommentRequest without both IssueID and Author.
- In loops, skip-and-log entries lacking an ID rather than sending empty requests.
When it happens
Trigger: Calling AddComment with publicops.AddCommentRequest{Author: "alice", Text: "note"} and IssueID unset; computing the issue ID from a variable that failed to populate (empty CLI arg, failed lookup); marshalling a request from user input where the issue field was never filled.
Common situations: CLI tools that derive the issue ID from the current branch name or a positional arg and get an empty string; automation that loops over a list where one entry lacks an ID; API consumers omitting the issue_id key in a JSON body.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- %w: add comment requires an author
- %w: comment text cannot be empty
- no store is open for this workspace
- not found
- no absolute native user directory is available
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c7c8c5c719020e67.
Report an issue: GitHub.