{"record":{"id":"5b8b38961f016ed7","repo":"gastownhall/beads","slug":"update-actor-and-issue-id-must-not-be-empty","errorCode":null,"errorMessage":"update: actor and issue ID must not be empty","messagePattern":"update: actor and issue ID must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/uow/issue_operations.go","lineNumber":527,"sourceCode":"\t\t}\n\t\treturn nil, false, err\n\t}\n\tif issue == nil {\n\t\treturn nil, false, fmt.Errorf(\"%w: issue %s\", publicops.ErrNotFound, id)\n\t}\n\treturn issue, false, nil\n}\n\nfunc validationError(err error) error {\n\tif errors.Is(err, publicops.ErrValidation) {\n\t\treturn err\n\t}\n\treturn fmt.Errorf(\"%w: %w\", publicops.ErrValidation, err)\n}\n\nfunc validateUpdateRequest(request publicops.UpdateRequest) error {\n\tif request.Actor == \"\" || request.IssueID == \"\" {\n\t\treturn validationError(fmt.Errorf(\"update: actor and issue ID must not be empty\"))\n\t}\n\tif err := storageissueops.ValidateUpdateRequest(request); err != nil {\n\t\treturn validationError(err)\n\t}\n\tif err := validateMetadataPatch(request.Patch.Metadata); err != nil {\n\t\treturn validationError(err)\n\t}\n\treturn nil\n}\n\nfunc validateCloseRequest(request publicops.CloseRequest) error {\n\tif request.Actor == \"\" || request.IssueID == \"\" {\n\t\treturn validationError(fmt.Errorf(\"close: actor and issue ID must not be empty\"))\n\t}\n\treturn nil\n}\n\nfunc validateMetadataPatch(metadata publicops.MetadataPatch) error {","sourceCodeStart":509,"sourceCodeEnd":545,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/uow/issue_operations.go#L509-L545","documentation":"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.","triggerScenarios":"Calling Update/applyUpdate with a publicops.UpdateRequest where request.Actor == \"\" or request.IssueID == \"\".","commonSituations":"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.","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"],"exampleFix":"// before\nreq := publicops.UpdateRequest{Patch: patch}\nerr := uc.Update(ctx, req)\n// after\nreq := publicops.UpdateRequest{Actor: \"agent\", IssueID: \"bd-123\", Patch: patch}\nerr := uc.Update(ctx, req)","handlingStrategy":"validation","validationCode":"func validUpdate(req publicops.UpdateRequest) error {\n    if req.Actor == \"\" { return fmt.Errorf(\"actor required\") }\n    if req.IssueID == \"\" { return fmt.Errorf(\"issue ID required\") }\n    return nil\n}","typeGuard":"func updateRequestComplete(req publicops.UpdateRequest) bool {\n    return req.Actor != \"\" && req.IssueID != \"\"\n}","tryCatchPattern":"if err := uc.Update(ctx, req); err != nil {\n    if errors.Is(err, publicops.ErrValidation) {\n        // bad input: fix request fields, do not retry\n        return err\n    }\n    return err\n}","preventionTips":["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"],"tags":["validation","update-request","go","empty-field"],"backgroundTag":"empty-required-field","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}