gastownhall/beads · error
update: actor and issue ID must not be empty
Error message
update: actor and issue ID must not be empty
What it means
validateUpdateRequest rejects updates whose Actor or IssueID fields are empty, wrapping the message in publicops.ErrValidation. The library requires an attribution actor and a target issue for every update.
Source
Thrown at internal/storage/uow/issue_operations.go:527
}
return nil, false, err
}
if issue == nil {
return nil, false, fmt.Errorf("%w: issue %s", publicops.ErrNotFound, id)
}
return issue, false, nil
}
func validationError(err error) error {
if errors.Is(err, publicops.ErrValidation) {
return err
}
return fmt.Errorf("%w: %w", publicops.ErrValidation, err)
}
func validateUpdateRequest(request publicops.UpdateRequest) error {
if request.Actor == "" || request.IssueID == "" {
return validationError(fmt.Errorf("update: actor and issue ID must not be empty"))
}
if err := storageissueops.ValidateUpdateRequest(request); err != nil {
return validationError(err)
}
if err := validateMetadataPatch(request.Patch.Metadata); err != nil {
return validationError(err)
}
return nil
}
func validateCloseRequest(request publicops.CloseRequest) error {
if request.Actor == "" || request.IssueID == "" {
return validationError(fmt.Errorf("close: actor and issue ID must not be empty"))
}
return nil
}
func validateMetadataPatch(metadata publicops.MetadataPatch) error {View on GitHub (pinned to 71377f2769)
Solutions
- Set request.Actor to the acting user/agent identity before calling Update
- Set request.IssueID to a valid existing issue key
- Validate fields before dispatch: if req.Actor == "" || req.IssueID == "" { fix }
- Check the source of these values (flags, env, config) for empty defaults
Example fix
// before
req := publicops.UpdateRequest{Patch: patch}
err := uc.Update(ctx, req)
// after
req := publicops.UpdateRequest{Actor: "agent", IssueID: "bd-123", Patch: patch}
err := uc.Update(ctx, req) Defensive patterns
Strategy: validation
Validate before calling
func validUpdate(req publicops.UpdateRequest) error {
if req.Actor == "" { return fmt.Errorf("actor required") }
if req.IssueID == "" { return fmt.Errorf("issue ID required") }
return nil
} Type guard
func updateRequestComplete(req publicops.UpdateRequest) bool {
return req.Actor != "" && req.IssueID != ""
} Try / catch
if err := uc.Update(ctx, req); err != nil {
if errors.Is(err, publicops.ErrValidation) {
// bad input: fix request fields, do not retry
return err
}
return err
} Prevention
- Use a constructor that requires actor and issueID parameters
- Never build requests from unverified config/env values — default-check them
- Add a lint/test asserting every Update call site sets Actor and IssueID
- Centralize request construction in one helper
When it happens
Trigger: Calling Update/applyUpdate with a publicops.UpdateRequest where request.Actor == "" or request.IssueID == "".
Common situations: Building the request programmatically and forgetting to set Actor, ID resolved from an empty config/env variable, a struct initialized but never populated, or a CLI flag not passed.
Related errors
- %w: claim cannot use expected assignee or status
- close: actor and issue ID must not be empty
- reopen: actor and issue ID must not be empty
- no store is open for this workspace
- not found
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5b8b38961f016ed7.
Report an issue: GitHub.