{"record":{"id":"25bc3811e530d353","repo":"gastownhall/beads","slug":"read-existing-export-w","errorCode":null,"errorMessage":"read existing export: %w","messagePattern":"read existing export: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/export_auto.go","lineNumber":1183,"sourceCode":"\t\t}\n\t}\n\tfor _, s := range b {\n\t\tif !seen[s] {\n\t\t\tseen[s] = true\n\t\t\tout = append(out, s)\n\t\t}\n\t}\n\treturn out\n}\n\n// rewriteExportFile applies a set of upserts and removals to an existing\n// JSONL export and writes the result atomically. upsertOrder preserves\n// append order for brand-new issue IDs; previously-present IDs keep their\n// original file position even when their bodies are replaced.\nfunc rewriteExportFile(path string, upserts map[string][]byte, removed map[string]bool, upsertOrder []string) (issueCount, memoryCount int, err error) {\n\tlines, err := loadExistingIssueLines(path)\n\tif err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"read existing export: %w\", err)\n\t}\n\n\t// Apply upserts: replace-in-place for known IDs, append (in input\n\t// order) for brand-new IDs. This keeps stable ordering across runs\n\t// instead of scrambling the file on every change.\n\tfor _, id := range upsertOrder {\n\t\tline, ok := upserts[id]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tlines.set(id, line)\n\t}\n\n\tfor id := range removed {\n\t\tlines.remove(id)\n\t}\n\n\tw, err := atomicfile.Create(path, 0o644)","sourceCodeStart":1165,"sourceCodeEnd":1201,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/export_auto.go#L1165-L1201","documentation":"rewriteExportFile loads the existing JSONL via loadExistingIssueLines before applying upserts/removals atomically. If reading the current export fails, the rewrite aborts with this wrapped error so the incremental export never clobbers a file it could not read — protecting against silent data loss.","triggerScenarios":"tryIncrementalExport calls rewriteExportFile, which calls loadExistingExportFile/loadExistingIssueLines(path) and gets a read/open/decode error — missing directory, permission denied, or malformed file when the reader rejects it.","commonSituations":".beads/issues.jsonl deleted or moved after the incremental path decided to use it; permission changes; disk full during read; corrupted JSONL from a crashed prior write.","solutions":["Regenerate the file with an explicit full export: `bd export -o .beads/issues.jsonl`, then retry `bd sync`","Restore the file from git history if it was deleted or corrupted","Fix filesystem-level issues (permissions, disk space) reported in the wrapped error"],"exampleFix":"// before\n// read existing export: open .beads/issues.jsonl: no such file or directory\n// after\nbd export -o .beads/issues.jsonl\nbd sync","handlingStrategy":"fallback","validationCode":"// Verify the export file exists and is readable before incremental sync\nif f, err := os.Open(\".beads/issues.jsonl\"); err != nil {\n    fmt.Println(\"export file missing/unreadable; do a full export\")\n} else {\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":"err := sync()\nif err != nil && strings.Contains(err.Error(), \"read existing export\") {\n    // Fall back: regenerate the file with an explicit full export\n    runCmd(\"bd\", \"export\", \"-o\", \".beads/issues.jsonl\")\n    err = sync()\n}","preventionTips":["Don't delete or move .beads/issues.jsonl while bd is running","Restore the file from git before syncing after manual surgery on it","Watch disk space on repos with large issue histories","Prefer bd commands over manual edits for changing the JSONL"],"tags":["file-io","incremental-export","jsonl"],"backgroundTag":"read-existing-export-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}