{"record":{"id":"cf2a3721387239d5","repo":"gastownhall/beads","slug":"close-id-must-not-be-empty","errorCode":null,"errorMessage":"close: id must not be empty","messagePattern":"close: id must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue.go","lineNumber":1665,"sourceCode":"}\n\nfunc (u *issueUseCaseImpl) CloseWisp(ctx context.Context, id string, params CloseIssueParams, actor string) (CloseIssueResult, error) {\n\treturn u.close(ctx, id, params, actor, true)\n}\n\n// CloseIssueChecked closes an issue through the shared guarded close path.\nfunc (u *issueUseCaseImpl) CloseIssueChecked(ctx context.Context, id string, params CloseIssueParams, actor string, force bool) (CloseIssueResult, error) {\n\treturn u.closeChecked(ctx, id, params, actor, force, false)\n}\n\n// CloseWispChecked is the wisp twin of CloseIssueChecked.\nfunc (u *issueUseCaseImpl) CloseWispChecked(ctx context.Context, id string, params CloseIssueParams, actor string, force bool) (CloseIssueResult, error) {\n\treturn u.closeChecked(ctx, id, params, actor, force, true)\n}\n\nfunc (u *issueUseCaseImpl) closeChecked(ctx context.Context, id string, params CloseIssueParams, actor string, force, useWisp bool) (CloseIssueResult, error) {\n\tif id == \"\" {\n\t\treturn CloseIssueResult{}, fmt.Errorf(\"close: id must not be empty\")\n\t}\n\tif actor == \"\" {\n\t\treturn CloseIssueResult{}, fmt.Errorf(\"close: actor must not be empty\")\n\t}\n\trow, err := u.issueRepo.CloseChecked(ctx, id, CloseRowParams{Reason: params.Reason, Session: params.Session}, actor, force)\n\tif err != nil {\n\t\treturn CloseIssueResult{}, fmt.Errorf(\"close %s: %w\", id, err)\n\t}\n\tissue, err := u.issueRepo.Get(ctx, id, IssueTableOpts{UseWispsTable: row.IsWisp || useWisp})\n\tif err != nil {\n\t\treturn CloseIssueResult{}, fmt.Errorf(\"close %s: reload: %w\", id, err)\n\t}\n\treturn CloseIssueResult{Issue: issue, Closed: !row.AlreadyClosed, OpenChildren: row.OpenChildren}, nil\n}\n\nfunc (u *issueUseCaseImpl) close(ctx context.Context, id string, params CloseIssueParams, actor string, useWisp bool) (CloseIssueResult, error) {\n\tif id == \"\" {\n\t\treturn CloseIssueResult{}, fmt.Errorf(\"close: id must not be empty\")","sourceCodeStart":1647,"sourceCodeEnd":1683,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue.go#L1647-L1683","documentation":"Guard clause in closeChecked: the issue/wisp ID argument is the empty string, so there is nothing to close. Pure input validation — no storage access happens.","triggerScenarios":"Calling CloseIssueChecked / CloseWispChecked (or CloseIssue/CloseWisp via close) with id=\"\" — e.g. an unset variable, empty parse result, or upstream failure that produced an empty identifier.","commonSituations":"Shell scripts where `bd close \"$ID\"` has unset ID; automation that reads issue IDs from a prior command that returned nothing; JSON templates with missing id field.","solutions":["Ensure the caller supplies a non-empty issue ID (e.g. bd-123).","Guard scripts: `[ -n \"$ID\" ] || exit 1` before invoking close.","Check the upstream command that produced the ID for silent failure.","Validate parsed input before constructing CloseIssueParams."],"exampleFix":"// before\nuc.CloseIssueChecked(ctx, id, params, actor, false)\n\n// after\nif id == \"\" {\n    return fmt.Errorf(\"cannot close: issue id is empty\")\n}\nuc.CloseIssueChecked(ctx, id, params, actor, false)","handlingStrategy":"validation","validationCode":"func validateCloseInput(id, actor string) error {\n    if id == \"\" {\n        return errors.New(\"close: issue id is required\")\n    }\n    if actor == \"\" {\n        return errors.New(\"close: actor is required\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"id must not be empty\") {\n        return fmt.Errorf(\"caller bug: no issue ID supplied; check upstream command output: %w\", err)\n    }\n    return err\n}","preventionTips":["Check command exit codes before reusing an ID variable in scripts.","Use `set -u` in bash so unset variables fail fast.","Validate API responses (issue IDs) before chaining calls.","Prefer structured output (--json) and parse explicitly."],"tags":["validation","close","input"],"backgroundTag":"empty-required-argument","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}