{"record":{"id":"5966565157703667","repo":"gastownhall/beads","slug":"failed-to-get-parent-child-deps-from-s-w","errorCode":null,"errorMessage":"failed to get parent-child deps from %s: %w","messagePattern":"failed to get parent-child deps from (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/epic_closure.go","lineNumber":54,"sourceCode":"\n\t// Step 2: Get parent-child dependencies from both tables (bd-w2w)\n\t// Wisp children store their parent-child deps in wisp_dependencies,\n\t// so we must check both tables to find all children of an epic.\n\tepicChildMap := make(map[string][]string)\n\tepicSet := make(map[string]bool, len(epicIDs))\n\tfor _, id := range epicIDs {\n\t\tepicSet[id] = true\n\t}\n\tfor _, depTable := range []string{\"dependencies\", \"wisp_dependencies\"} {\n\t\tdepRows, err := tx.QueryContext(ctx, fmt.Sprintf(`\n\t\t\tSELECT %s AS parent_id, issue_id FROM %s\n\t\t\tWHERE type = 'parent-child' AND %s IS NOT NULL\n\t\t`, DepTargetExpr, depTable, DepTargetExpr))\n\t\tif err != nil {\n\t\t\tif optionalBlockedTable(depTable) && isTableNotExistError(err) {\n\t\t\t\tcontinue // wisp_dependencies may not exist on pre-migration databases\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"failed to get parent-child deps from %s: %w\", depTable, err)\n\t\t}\n\t\tfor depRows.Next() {\n\t\t\tvar parentID, childID string\n\t\t\tif err := depRows.Scan(&parentID, &childID); err != nil {\n\t\t\t\tdepRows.Close()\n\t\t\t\treturn nil, fmt.Errorf(\"scan parent-child dep from %s: %w\", depTable, err)\n\t\t\t}\n\t\t\tif epicSet[parentID] {\n\t\t\t\tepicChildMap[parentID] = append(epicChildMap[parentID], childID)\n\t\t\t}\n\t\t}\n\t\tdepRows.Close()\n\t}\n\n\t// Step 3: Batch-fetch statuses for all child issues across all epics\n\tallChildIDs := make([]string, 0)\n\tfor _, children := range epicChildMap {\n\t\tallChildIDs = append(allChildIDs, children...)","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/epic_closure.go#L36-L72","documentation":"The function then loads parent-child dependencies from each dependencies table (issues and, optionally, wisps). If querying a table fails — and it is not the tolerable 'wisp_dependencies missing on pre-migration DB' case — the error is wrapped with the offending table name. It means the parent-child relationship data could not be read, so closure eligibility cannot be computed.","triggerScenarios":"Calling GetEpicsEligibleForClosureInTx when the `SELECT ... FROM <depTable> WHERE type='parent-child'` query fails on a table that does exist — connection error, missing expected columns (DepTargetExpr), or a corrupt dependencies table.","commonSituations":"Schema drift where `dependencies` lacks columns bd expects (older bd created the DB); database locks from a concurrent writer; wisp_dependencies existing but malformed.","solutions":["Note the table name in the message and inspect its schema against bd's expected columns.","Run pending migrations so dependencies/wisp_dependencies match the current schema.","Retry if the wrapped cause is a transient lock or connection error.","Check the wrapped error for 'unknown column' and repair or recreate the dependencies table."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for _, t := range []string{\"dependencies\", \"wisp_dependencies\"} {\n    if !tableExists(db, t) { return fmt.Errorf(\"%s missing; run migrations\", t) }\n}","typeGuard":"func isDepQueryErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to get parent-child deps from\")\n}","tryCatchPattern":"epics, err := GetEpicsEligibleForClosureInTx(ctx, tx)\nif err != nil {\n    if isDepQueryErr(err) {\n        if table := extractTable(err); !tableExists(db, table) { return migrateThenRetry(ctx) }\n    }\n    return err\n}","preventionTips":["Keep the schema current with bd releases before running closure jobs.","Avoid concurrent writers during dependency-graph reads.","Verify dependencies table columns match bd's expected DepTargetExpr columns after upgrades.","Backup the DB before schema-affecting operations."],"tags":["go","sql","storage","schema"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}