{"record":{"id":"a3b888fde06b1777","repo":"gastownhall/beads","slug":"w-comment-text-cannot-be-empty","errorCode":null,"errorMessage":"%w: comment text cannot be empty","messagePattern":"%w: comment text cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/commenter.go","lineNumber":28,"sourceCode":"\tpublicops \"github.com/steveyegge/beads/issueops\"\n)\n\n// ValidateAddCommentRequest applies the request rules every Commenter\n// implementation shares.\n//\n// Blankness is decided on a TRIMMED copy and the request's own Text is left\n// alone: a comment of nothing but whitespace carries no information and is\n// almost always a shell quoting accident, but a comment that merely begins\n// with a newline is a comment.\nfunc ValidateAddCommentRequest(request publicops.AddCommentRequest) error {\n\tif request.Author == \"\" {\n\t\treturn fmt.Errorf(\"%w: add comment requires an author\", storage.ErrValidation)\n\t}\n\tif request.IssueID == \"\" {\n\t\treturn fmt.Errorf(\"%w: add comment requires an issue ID\", storage.ErrValidation)\n\t}\n\tif strings.TrimSpace(request.Text) == \"\" {\n\t\treturn fmt.Errorf(\"%w: comment text cannot be empty\", storage.ErrValidation)\n\t}\n\treturn nil\n}\n\n// AddCommentCommitMessage is the history entry a comment records. It is the\n// spelling both stores' own AddIssueComment already wrote.\nfunc AddCommentCommitMessage(issueID string) string {\n\treturn \"bd: comment \" + issueID\n}\n\n// ExecuteAddComment appends one comment in tx and reports the durable tables\n// changed. It is the store-backed body behind the Commenter accessor; the\n// unit-of-work provider has its own, for the reason Lifecycle does.\n//\n// A comment on an ephemeral row changes only wisp_comments, which\n// ChangedTables drops, so the caller's transaction commits nothing and records\n// no history entry: the wisp tables are dolt-ignored and there is nothing to\n// version.","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/commenter.go#L10-L46","documentation":"ValidateAddCommentRequest rejects comment text that is empty or whitespace-only, judged on a TRIMMED copy (strings.TrimSpace(request.Text) == \"\"). A whitespace-only comment carries no information and is almost always a shell quoting accident, so it is refused with wrapped storage.ErrValidation. Note the original Text is left unmodified — text that merely begins with a newline is valid.","triggerScenarios":"Calling AddComment with Text: \"\" or Text: \"   \"; shell invocations where quoting collapsed (bd comment bd-1 \"$EMPTY\") producing only spaces; editor integrations saving a comment body that is only blank lines.","commonSituations":"Shell scripts where a variable interpolates to nothing due to a failed subcommand or unset var; users hitting enter on an empty editor prompt; automated pipelines forwarding a log field that turned out to be whitespace.","solutions":["Provide non-whitespace comment text in AddCommentRequest.Text.","In scripts, check [ -n \"$(printf '%s' \"$text\" | tr -d '[:space:]')\" ] before invoking, or set -u to catch unset variables.","Classify with errors.Is(err, storage.ErrValidation) and treat it as a caller bug, not a transient failure."],"exampleFix":"// before\nexec.Command(\"bd\", \"comment\", id, body) // body may be \"   \"\n\n// after\nif strings.TrimSpace(body) == \"\" {\n\treturn fmt.Errorf(\"refusing to add blank comment to %s\", id)\n}\nexec.Command(\"bd\", \"comment\", id, body)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(text) == \"\" {\n\treturn errors.New(\"comment text is blank; refusing to comment\")\n}","typeGuard":null,"tryCatchPattern":"if err := store.AddComment(ctx, req); err != nil {\n\tif errors.Is(err, storage.ErrValidation) && strings.TrimSpace(req.Text) == \"\" {\n\t\treturn fmt.Errorf(\"blank comment (check shell quoting): %w\", err)\n\t}\n\treturn err\n}","preventionTips":["In shell scripts, quote variables (\"$text\") and enable set -u to catch unset values.","Trim-check text before submitting; leading newlines are fine, whitespace-only is not.","Log the exact text (escaped) when validation fails to spot quoting accidents."],"tags":["validation","comments","go"],"backgroundTag":"empty-required-field","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}