{"record":{"id":"379b71cd46bbf019","repo":"gastownhall/beads","slug":"createmany-d-w","errorCode":null,"errorMessage":"createMany[%d]: %w","messagePattern":"createMany\\[(.+?)\\]: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/issue.go","lineNumber":1088,"sourceCode":"\t\t}\n\t}\n\treturn fmt.Errorf(\"%w: issue ID %s does not match configured prefix %s\", storage.ErrPrefixMismatch, id, prefix)\n}\n\nfunc (u *issueUseCaseImpl) CreateIssues(ctx context.Context, params []CreateIssueParams, actor string) (CreateIssuesResult, error) {\n\treturn u.createMany(ctx, params, actor, false)\n}\n\nfunc (u *issueUseCaseImpl) CreateWisps(ctx context.Context, params []CreateIssueParams, actor string) (CreateIssuesResult, error) {\n\treturn u.createMany(ctx, params, actor, true)\n}\n\nfunc (u *issueUseCaseImpl) createMany(ctx context.Context, params []CreateIssueParams, actor string, useWisp bool) (CreateIssuesResult, error) {\n\tresult := CreateIssuesResult{}\n\tfor i := range params {\n\t\tr, err := u.create(ctx, params[i], actor, useWisp)\n\t\tif err != nil {\n\t\t\treturn result, fmt.Errorf(\"createMany[%d]: %w\", i, err)\n\t\t}\n\t\tresult.Issues = append(result.Issues, r.Issue)\n\t}\n\treturn result, nil\n}\n\nfunc (u *issueUseCaseImpl) ApplyIssueGraph(ctx context.Context, plan GraphPlan, actor string) (GraphApplyResult, error) {\n\treturn u.applyGraph(ctx, plan, actor, false)\n}\n\nfunc (u *issueUseCaseImpl) ApplyWispGraph(ctx context.Context, plan GraphPlan, actor string) (GraphApplyResult, error) {\n\treturn u.applyGraph(ctx, plan, actor, true)\n}\n\nfunc (u *issueUseCaseImpl) applyGraph(ctx context.Context, plan GraphPlan, actor string, useWisp bool) (GraphApplyResult, error) {\n\tkeyToID := make(map[string]string, len(plan.Nodes))\n\tpendingAssignees := make(map[int]string, len(plan.Nodes))\n","sourceCodeStart":1070,"sourceCodeEnd":1106,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/issue.go#L1070-L1106","documentation":"Wraps any error from the per-issue create call during batch creation (createMany), annotated with the index of the failing item in the params slice. Batch creation is not transactional across items in this wrapper — it returns immediately on the first failure, so earlier issues may already be persisted.","triggerScenarios":"Calling CreateIssues (or wisp variant) with a params slice where item i fails u.create for any reason: validation, prefix mismatch, dep insert failure, storage error.","commonSituations":"Bulk imports where one entry is malformed or duplicates an existing ID; one item referencing a dependency that doesn't exist; partial import state because earlier items succeeded before the failure.","solutions":["Read the inner error and the index N to identify the exact failing params entry","Fix or drop the offending item at index N and re-run the remaining items","Make creation idempotent (check for existing IDs) to safely retry after partial success","Pre-validate all params (titles, IDs, deps) before calling createMany"],"exampleFix":"// before: one bad item aborts the batch mid-way\nparams := []CreateIssueParams{good1, badDep, good2}\nresult, err := uc.CreateIssues(ctx, params, actor)\n// after: pre-validate each item\nfor i, p := range params {\n    if err := validate(p); err != nil { log.Printf(\"skipping item %d: %v\", i, err); continue }\n}","handlingStrategy":"try-catch","validationCode":"for i, p := range params {\n    if p.Issue.Title == \"\" || p.Issue.ID == \"\" {\n        return fmt.Errorf(\"params[%d] missing title or id\", i)\n    }\n    if existing, _ := uc.GetIssue(ctx, p.Issue.ID); existing != nil {\n        return fmt.Errorf(\"params[%d] duplicates existing %s\", i, p.Issue.ID)\n    }\n}","typeGuard":null,"tryCatchPattern":"result, err := uc.CreateIssues(ctx, params, actor)\nif err != nil {\n    var idx int\n    if _, scanErr := fmt.Sscanf(err.Error(), \"createMany[%d]\", &idx); scanErr == nil {\n        // resume from params[idx:] after fixing or skipping\n        return retryFrom(ctx, params[idx:], actor)\n    }\n}","preventionTips":["Pre-validate all params before batch create","Treat creation as partially applied: check which IDs already exist before retrying","Make IDs idempotent or deduplicate inputs","Keep batches small to limit partial-failure blast radius"],"tags":["storage","batch-create","go","validation"],"backgroundTag":"batch-create-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}