gastownhall/beads · error
failed to open JSONL: %w
Error message
failed to open JSONL: %w
What it means
validateJSONLForMigration opens the .beads/issues.jsonl export to validate it before a migration. If os.Open fails, the error is wrapped as 'failed to open JSONL' and validation aborts with zero counts. Usually this simply means the JSONL file does not exist at the expected path.
Source
Thrown at cmd/bd/doctor/migration_validation.go:387
// findJSONLFile locates the JSONL file in a .beads directory.
// Temporary: will be removed with Phase 2c (doctor JSONL cleanup).
func findJSONLFile(beadsDir string) string {
for _, name := range []string{"issues.jsonl", "beads.jsonl"} {
p := filepath.Join(beadsDir, name)
if _, err := os.Stat(p); err == nil {
return p
}
}
return ""
}
// validateJSONLForMigration validates a JSONL file for migration readiness.
// Returns: count of valid issues, count of malformed lines, set of valid IDs, and error if blocking.
func validateJSONLForMigration(jsonlPath string) (int, int, map[string]bool, error) {
file, err := os.Open(jsonlPath) //nolint:gosec
if err != nil {
return 0, 0, nil, fmt.Errorf("failed to open JSONL: %w", err)
}
defer file.Close()
ids := make(map[string]bool)
var malformed int
var parseErrors []string
scanner := bufio.NewScanner(file)
scanner.Buffer(make([]byte, 0, 1024), 2*1024*1024) // 2MB buffer for large lines
lineNo := 0
for scanner.Scan() {
lineNo++
line := scanner.Bytes()
if len(line) == 0 {
continue
}
View on GitHub (pinned to 71377f2769)
Solutions
- Generate the export first: run bd sync (or bd export) so .beads/issues.jsonl exists.
- Verify the path: ls -la <path>/.beads/issues.jsonl and correct --path if wrong.
- Fix file permissions (chmod u+r) if the file exists but is unreadable.
- Ensure the path is a file, not a directory, if it was replaced by something odd.
Example fix
// before $ bd doctor migrate-check Error: failed to open JSONL: open .beads/issues.jsonl: no such file or directory // after $ bd sync $ bd doctor migrate-check ✓ JSONL valid
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(jsonlPath)
if err != nil {
return fmt.Errorf("JSONL not ready for migration check: %w (run bd sync first)", err)
}
if info.IsDir() {
return fmt.Errorf("%s is a directory, expected a file", jsonlPath)
} Try / catch
valid, malformed, ids, err := validateJSONLForMigration(jsonlPath)
if err != nil {
var perr *fs.PathError
if errors.As(err, &perr) && os.IsNotExist(perr) {
return fmt.Errorf("run 'bd sync' to generate %s before migration", jsonlPath)
}
return err
} Prevention
- Always run bd sync (or bd export) before migration readiness checks.
- Confirm .beads/issues.jsonl exists at the exact path passed to doctor.
- Keep read permissions on .beads for the user running bd.
- Verify --path points at the repo root, not a subdirectory.
When it happens
Trigger: os.Open(jsonlPath) returns an error — file missing (ENOENT), permission denied, or the path is a directory. Raised when CheckMigrationReadiness or CheckMigrationCompletion calls this validator.
Common situations: Running migration checks before ever running bd sync (no export yet); typo'd or wrong --path to the beads dir; JSONL deleted or never committed; permissions changed by another tool.
Related errors
- failed to read JSONL: %w
- building hook migration plan: %w
- applying hook migration: %w
- failed to read JSONL file %s: %w
- failed to migrate database %s to %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5c94aa3c93ef239b.
Report an issue: GitHub.