gastownhall/beads · error

%w: add comment requires an author

Error message

%w: add comment requires an author

What it means

ValidateAddCommentRequest rejects an AddCommentRequest whose Author field is the empty string. Beads records who wrote every comment, and an anonymous comment cannot be attributed in history or rendered, so the request is refused before any database work with a wrapped storage.ErrValidation sentinel. Fix the request, not the store.

Source

Thrown at internal/storage/issueops/commenter.go:22

	"context"
	"database/sql"
	"fmt"
	"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

View on GitHub (pinned to 71377f2769)

Solutions

  1. Set request.Author to a non-empty identifier (username or email) before calling AddComment.
  2. If the author comes from an env var or config, check it is non-empty at startup and fail early with a clear message.
  3. Use errors.Is(err, storage.ErrValidation) to classify this refusal and surface it as a 400-style error rather than an internal failure.

Example fix

// before
req := publicops.AddCommentRequest{IssueID: issueID, Text: text}
err := store.AddComment(ctx, req)

// after
author := os.Getenv("BD_USER")
if author == "" {
	return fmt.Errorf("BD_USER must be set to comment")
}
req := publicops.AddCommentRequest{IssueID: issueID, Author: author, Text: text}
err := store.AddComment(ctx, req)
Defensive patterns

Strategy: validation

Validate before calling

func validCommentRequest(r publicops.AddCommentRequest) error {
	if r.Author == "" { return errors.New("author required") }
	if r.IssueID == "" { return errors.New("issue ID required") }
	if strings.TrimSpace(r.Text) == "" { return errors.New("comment text required") }
	return nil
}

Try / catch

if err := store.AddComment(ctx, req); err != nil {
	if errors.Is(err, storage.ErrValidation) {
		return fmt.Errorf("bad comment request: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling AddComment (or ExecuteAddComment via any Commenter) with publicops.AddCommentRequest{IssueID: "bd-1", Text: "hi"} and Author left unset; building the request struct by field name and forgetting Author; deserializing a JSON payload that omits the author field.

Common situations: Scripts that construct AddCommentRequest programmatically after reading an author from config or env (BD_USER, git config user.email) and hit an unset variable; API wrappers that map an incoming payload with a missing/empty author field; tests that reuse a partially-filled request struct.

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


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