gastownhall/beads · error
failed to parse JSONL line: %w
Error message
failed to parse JSONL line: %w
What it means
After reading the file, parseJSONLFile unmarshals each non-empty line first into a peek map (map[string]json.RawMessage) to inspect the `_type` field. If any line is not valid JSON, the parse fails with `failed to parse JSONL line:` wrapping the json error. Every line of a JSONL file must be a complete, standalone JSON object.
Source
Thrown at cmd/bd/import_shared.go:1006
return nil, nil, fmt.Errorf("failed to read JSONL file %s: %w", path, err)
}
scanner := bufio.NewScanner(strings.NewReader(string(data)))
// Allow up to 64MB per line for large descriptions
scanner.Buffer(make([]byte, 0, 1024*1024), 64*1024*1024)
var issues []*types.Issue
configEntries := make(map[string]string)
for scanner.Scan() {
line := scanner.Text()
if line == "" {
continue
}
// Peek at the record to check for _type field
var peek map[string]json.RawMessage
if err := json.Unmarshal([]byte(line), &peek); err != nil {
return nil, nil, fmt.Errorf("failed to parse JSONL line: %w", err)
}
// Skip the optional beads-jsonl metadata/header record.
// Canonical exports produced by the stable-ordering /
// git-merge convention prepend a schema+provenance line, e.g.
// {"_schema":"beads-jsonl/1","_dolt_branch":"main",
// "_dolt_commit":"...","_sort":"stable-v1"}. It carries no
// _type and no issue fields; without this guard it falls
// through to the issue path, unmarshals into an empty Issue,
// and aborts the whole import with "validation failed for
// issue : title is required". Identified by the _schema
// sentinel, which real issue/memory records never carry.
if _, isHeader := peek["_schema"]; isHeader {
continue
}
// Check if this is a memory record
if rawType, ok := peek["_type"]; ok {View on GitHub (pinned to 71377f2769)
Solutions
- The error names the line offset/cause — open the file at that line and fix or remove the malformed line.
- Validate the whole file: `while IFS= read -r l; do echo "$l" | jq empty || echo BAD; done < file.jsonl` (or `jq -s . file.jsonl`).
- Re-export from the source (`bd export -o file.jsonl`) instead of hand-repairing a corrupted copy.
- Check for git merge-conflict markers or duplicated/concatenated lines if the file was merged or concatenated.
Example fix
// before (file line 42)
{"id":"bd-42" "title":"broken"} # missing comma
// after
{"id":"bd-42","title":"broken"} # valid JSON, or re-export via bd export Defensive patterns
Strategy: validation
Validate before calling
func validateJSONL(path string) error {
f, err := os.Open(path)
if err != nil { return err }
defer f.Close()
sc := bufio.NewScanner(f)
for i := 1; sc.Scan(); i++ {
line := strings.TrimSpace(sc.Text())
if line == "" { continue }
if err := json.Unmarshal([]byte(line), new(map[string]json.RawMessage)); err != nil {
return fmt.Errorf("line %d: %w", i, err)
}
}
return sc.Err()
}
// run validateJSONL(path) before bd import Type guard
func isJSONObject(line []byte) bool {
var m map[string]json.RawMessage
return json.Unmarshal(line, &m) == nil
} Try / catch
if err := importFrom(path); err != nil {
if strings.Contains(err.Error(), "failed to parse JSONL line") {
return fmt.Errorf("malformed JSONL; validate with `jq empty` per line, or re-export: %w", err)
}
return err
} Prevention
- Always re-export with `bd export -o file.jsonl` instead of hand-editing exports.
- Never concatenate JSONL exports without guaranteeing one object per line.
- Check for git merge-conflict markers in shared export files.
- Validate each line with `jq empty` before importing.
When it happens
Trigger: `bd import file.jsonl` where a line contains malformed JSON: truncated writes, hand-edited lines with syntax errors, concatenated exports (two objects on one line), binary corruption, or smart-quote/copy-paste artifacts.
Common situations: A partially downloaded or interrupted export file; manual edits to issue descriptions breaking quoting/escaping; merging export files with a tool that didn't preserve line-per-record format; a git merge conflict marker left inside the file.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- parsing JSON: %w
- failed to parse gh output: %w
- parse gh output: %w
- failed to parse JSONL line: %w
- failed to parse memory record: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0ceb580217d8d872.
Report an issue: GitHub.