{"record":{"id":"553741be7de98eda","repo":"gastownhall/beads","slug":"getnewlyunblockedbyclose-closedid-must-not-be-emp","errorCode":null,"errorMessage":"GetNewlyUnblockedByClose: closedID must not be empty","messagePattern":"GetNewlyUnblockedByClose: closedID must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue.go","lineNumber":1778,"sourceCode":"\tfor _, child := range children {\n\t\tif child.Status != types.StatusClosed {\n\t\t\topen++\n\t\t}\n\t}\n\treturn open, nil\n}\n\nfunc (u *issueUseCaseImpl) GetNewlyUnblockedByClose(ctx context.Context, closedID string) ([]*types.Issue, error) {\n\treturn u.getNewlyUnblockedByClose(ctx, closedID)\n}\n\nfunc (u *issueUseCaseImpl) GetNewlyUnblockedByCloseWisp(ctx context.Context, closedID string) ([]*types.Issue, error) {\n\treturn u.getNewlyUnblockedByClose(ctx, closedID)\n}\n\nfunc (u *issueUseCaseImpl) getNewlyUnblockedByClose(ctx context.Context, closedID string) ([]*types.Issue, error) {\n\tif closedID == \"\" {\n\t\treturn nil, fmt.Errorf(\"GetNewlyUnblockedByClose: closedID must not be empty\")\n\t}\n\tout, err := u.issueRepo.GetNewlyUnblockedByClose(ctx, closedID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GetNewlyUnblockedByClose %s: %w\", closedID, err)\n\t}\n\treturn out, nil\n}\n\nfunc (u *issueUseCaseImpl) ClaimReadyIssue(ctx context.Context, filter types.WorkFilter, actor string) (ClaimReadyResult, error) {\n\treturn u.claimReady(ctx, filter, actor, false)\n}\n\nfunc (u *issueUseCaseImpl) ClaimReadyWisp(ctx context.Context, filter types.WorkFilter, actor string) (ClaimReadyResult, error) {\n\treturn u.claimReady(ctx, filter, actor, true)\n}\n\nfunc (u *issueUseCaseImpl) claimReady(ctx context.Context, filter types.WorkFilter, actor string, useWisp bool) (ClaimReadyResult, error) {\n\tvar (","sourceCodeStart":1760,"sourceCodeEnd":1796,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue.go#L1760-L1796","documentation":"A guard-clause validation error from getNewlyUnblockedByClose: it refuses to run when closedID is an empty string. The library requires the ID of the issue that was just closed to compute which dependents became unblocked; an empty ID is a programming/caller bug, not a storage failure. Unlike its sibling error at line 1782, nothing is wrapped — this is raised before any repository call.","triggerScenarios":"Calling GetNewlyUnblockedByClose or GetNewlyUnblockedByCloseWisp with an empty closedID string, typically because an upstream variable holding the closed issue's ID was never populated (empty result, missing field, or zero-value Issue.ID).","commonSituations":"Hook/workflow code reacting to an issue close event where the event payload's ID field is empty; constructing the call from a parsed CLI argument that was omitted; deserializing JSON into a struct where the id key name mismatched.","solutions":["Ensure the closed issue's ID is captured before calling; log or check it at the call site","Skip the call entirely when the ID is empty (empty ID means nothing to look up)","Trace upstream to find why the ID was zero-valued (missing JSON field, unfilled struct, dropped CLI flag)"],"exampleFix":"// before\nunblocked, err := uc.GetNewlyUnblockedByClose(ctx, closedID)\n// after\nif closedID == \"\" {\n    return nil // nothing closed; skip\n}\nunblocked, err := uc.GetNewlyUnblockedByClose(ctx, closedID)","handlingStrategy":"validation","validationCode":"if closedID == \"\" {\n    return nil // skip: nothing was closed\n}\n// safe to call\nout, err := uc.GetNewlyUnblockedByClose(ctx, closedID)","typeGuard":"func validIssueID(id string) bool { return id != \"\" }","tryCatchPattern":null,"preventionTips":["Check for empty IDs at event/hook boundaries before calling unblock logic","Fail fast in constructors/parsers when an expected issue ID is missing","Log the upstream source of closedID to trace empty values","Treat empty ID as a no-op rather than an error in close workflows"],"tags":["go","validation","empty-input","argument-check"],"backgroundTag":"missing-required-argument","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}