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

  1. The error names the line offset/cause — open the file at that line and fix or remove the malformed line.
  2. Validate the whole file: `while IFS= read -r l; do echo "$l" | jq empty || echo BAD; done < file.jsonl` (or `jq -s . file.jsonl`).
  3. Re-export from the source (`bd export -o file.jsonl`) instead of hand-repairing a corrupted copy.
  4. 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

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

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/0ceb580217d8d872. Report an issue: GitHub.