{"record":{"id":"7f0e9f5382fbb08f","repo":"gastownhall/beads","slug":"import-dependency-pass-chunk-d-d-failed-all-d","errorCode":null,"errorMessage":"import dependency pass chunk %d/%d failed (all %d issue rows are committed; re-run the import to resume — it converges): %w","messagePattern":"import dependency pass chunk (.+?)/(.+?) failed \\(all (.+?) issue rows are committed; re-run the import to resume — it converges\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/import_shared.go","lineNumber":431,"sourceCode":"\t\treturn nil\n\t}\n\tdepOpts := opts\n\t// Never rewrite an existing row here: the import's row write already\n\t// happened in phase 1, and a concurrent update since then must win. With\n\t// ConflictSkip the engine leaves the stored row untouched and still wires\n\t// the batch's dependencies.\n\tdepOpts.ConflictSkip = true\n\t// No row write can be stale-rejected under ConflictSkip; leaving the\n\t// callback unset keeps a phase-2 signal from ever misreporting a row\n\t// whose phase-1 write committed.\n\tdepOpts.OnStaleRejected = nil\n\tdepTotal := len(depRows)\n\tdepChunks := (depTotal + importChunkSize - 1) / importChunkSize\n\tfor start, chunk := 0, 1; start < depTotal; start, chunk = start+importChunkSize, chunk+1 {\n\t\tend := min(start+importChunkSize, depTotal)\n\t\tpacer.beforeTx()\n\t\tif err := store.CreateIssuesWithFullOptions(ctx, depRows[start:end], actor, depOpts); err != nil {\n\t\t\treturn fmt.Errorf(\"import dependency pass chunk %d/%d failed (all %d issue rows are committed; re-run the import to resume — it converges): %w\", chunk, depChunks, rowTotal, err)\n\t\t}\n\t\tfmt.Fprintf(importProgress, \"bd import: deferred dependencies wired for %d/%d issues\\n\", end, depTotal) //nolint:gosec // G705: stderr, not a browser context\n\t}\n\treturn nil\n}\n\n// orderImportIssuesForChunking returns the issues reordered so that every valid\n// readiness-affecting edge (blocks, parent-child, conditional-blocks, waits-for;\n// the types GetReadyWork consults) points at a row in the same or an earlier\n// chunk, which lets the import wire that edge in the same transaction as the\n// row. It runs Kahn's algorithm over the intra-batch readiness edges, seeded in\n// file order so unconstrained rows keep their relative order; duplicate IDs are\n// chained in file order to preserve last-row-wins upsert semantics.\n//\n// A readiness cycle (invalid for blocking types; only ever present in the\n// corrupted or legacy JSONL the import tolerates) cannot be fully ordered.\n// Appending the stalled rows in plain file order — as an earlier version did —\n// can place a valid dependent of a cycle before the cycle member it blocks on,","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/import_shared.go#L413-L449","documentation":"In the chunked classic import, issue rows are committed first, then a second pass wires deferred dependency rows in chunks. If a dependency-pass chunk fails, ALL issue rows are already durably committed — only the dependency edges are incomplete. The error states the row count committed and that re-running the import converges: the rows will be updated in place and the missing dependencies wired.","triggerScenarios":"`bd import` where the issue-row pass succeeded but a dependency-pass CreateIssuesWithFullOptions chunk failed — storage lock contention, disk error, or a dependency row failing constraints (e.g. a dependency referencing an issue that failed filtering/validation).","commonSituations":"Concurrent bd process grabbing the SQLite write lock between the row pass and the dep pass; large dependency graphs on a flaky disk; mixed-bucket dependency policy dropping a referenced issue so its dep row errors.","solutions":["Re-run the same import — all issue rows are committed; the retry wires the missing dependencies and converges.","Fix the underlying storage issue named by the wrapped error (locks, disk, connectivity) before retrying.","If it recurs, inspect the dependency records in the JSONL for references to nonexistent or filtered-out issues.","Reduce competing bd activity during imports to avoid lock contention between passes."],"exampleFix":"// before\nbd import big.jsonl   # dependency pass chunk 2/3 failed (all 500 issue rows are committed...)\n// after\n# ensure no competing locks, then re-run:\nbd import big.jsonl   # completes dependency wiring","handlingStrategy":"retry","validationCode":"// validate dependency references exist before import\nids := map[string]bool{}\nfor _, iss := range issues { ids[iss.ID] = true }\nfor _, iss := range issues {\n    for _, d := range iss.Dependencies {\n        if !ids[d.DependsOnID] { return fmt.Errorf(\"dep on missing issue %s\", d.DependsOnID) }\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := importIssuesChunked(ctx, store, issues, actor, opts); err != nil {\n    if strings.Contains(err.Error(), \"dependency pass\") {\n        // all issue rows committed; retry wires remaining deps and converges\n        return retry(2, time.Second, func() error {\n            return importIssuesChunked(ctx, store, issues, actor, opts)\n        })\n    }\n    return err\n}","preventionTips":["Include all referenced issues in the import file so dependency rows resolve.","Avoid concurrent bd writers between the row pass and the dep pass.","Re-run the import after a dependency-pass failure; committed rows are safe.","Check disk/storage health before very large dependency graphs."],"tags":["import","dependencies","chunking","resume"],"backgroundTag":"import-dependency-pass-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}