{"record":{"id":"6324821f7dd37a36","repo":"gastownhall/beads","slug":"get-next-child-id-iterate-children-w","errorCode":null,"errorMessage":"get next child ID: iterate children: %w","messagePattern":"get next child ID: iterate children: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/child_id.go","lineNumber":48,"sourceCode":"\t\t  AND id NOT LIKE CONCAT(?, '.%%.%%')\n\t`, issueTable), parentID, parentID)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"get next child ID: query existing children: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tfor rows.Next() {\n\t\tvar id string\n\t\tif err := rows.Scan(&id); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"get next child ID: scan child row: %w\", err)\n\t\t}\n\t\t_, childNum, ok := ParseHierarchicalID(id)\n\t\tif ok && childNum > lastChild {\n\t\t\tlastChild = childNum\n\t\t}\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn \"\", fmt.Errorf(\"get next child ID: iterate children: %w\", err)\n\t}\n\n\tnextChild := lastChild + 1\n\n\t//nolint:gosec // G201: counterTable is one of two hardcoded constants.\n\tif _, err := tx.ExecContext(ctx, fmt.Sprintf(`\n\t\tINSERT INTO %s (parent_id, last_child) VALUES (?, ?)\n\t\tON DUPLICATE KEY UPDATE last_child = ?\n\t`, counterTable), parentID, nextChild, nextChild); err != nil {\n\t\treturn \"\", fmt.Errorf(\"get next child ID: update counter: %w\", err)\n\t}\n\n\treturn fmt.Sprintf(\"%s.%d\", parentID, nextChild), nil\n}\n","sourceCodeStart":30,"sourceCodeEnd":63,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/child_id.go#L30-L63","documentation":"After the child-ID loop finishes, rows.Err() reports any deferred iteration error (e.g. connection loss during streaming); bd wraps it as \"get next child ID: iterate children: %w\". This catches failures that only surface after all rows appear consumed, preventing an undercounted child number.","triggerScenarios":"Completing rows.Next() iteration when the connection broke mid-stream, the context was cancelled during iteration, or the driver hit a protocol error after partial reads.","commonSituations":"Large parents with thousands of children streamed over a flaky remote Dolt connection; cancelled bd commands mid-create; server timeouts on long result sets.","solutions":["Retry the create; iteration-level connection errors are typically transient.","Increase timeouts / avoid cancelling bd during large child creation batches.","Verify child numbering afterwards (bd show parent) to ensure no duplicate child IDs were produced before the retry.","For remote Dolt servers, check network stability; prefer local embedded mode for very large parents."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := rows.Err(); err != nil { /* inside lib */ }\n// caller side:\nif err != nil {\n    tx.Rollback()\n    return retry(fmt.Errorf(\"iterate children failed: %w\", err))\n}","preventionTips":["Avoid cancelling bd commands during large hierarchical creates.","Increase DB timeouts for parents with many children.","Prefer embedded/local Dolt mode when streaming large result sets over unreliable networks.","Always retry the whole transaction after an iteration error; partial state rolls back."],"tags":["database","sql","iteration","connection"],"backgroundTag":"sql-rows-iteration-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}