gastownhall/beads · error

failed to parse memory record: %w

Error message

failed to parse memory record: %w

What it means

Lines whose peek map has `_type: "memory"` are unmarshaled into a memoryRecord struct. If that unmarshal fails (a JSON-valid line whose fields don't match the memory record schema — e.g. wrong types), the import aborts with `failed to parse memory record:` wrapping the json error. This is a schema mismatch, not a JSON syntax problem — line 798's syntax check already passed.

Source

Thrown at cmd/bd/import_shared.go:1029

		// 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 {
			var typeStr string
			if err := json.Unmarshal(rawType, &typeStr); err == nil && typeStr == "memory" {
				var mem memoryRecord
				if err := json.Unmarshal([]byte(line), &mem); err != nil {
					return nil, nil, fmt.Errorf("failed to parse memory record: %w", err)
				}
				if mem.Key != "" && mem.Value != "" {
					configEntries[kvPrefix+memoryPrefix+mem.Key] = mem.Value
				}
				continue
			}
		}

		// Regular issue record
		var issue types.Issue
		if err := json.Unmarshal([]byte(line), &issue); err != nil {
			return nil, nil, fmt.Errorf("failed to parse issue from JSONL: %w", err)
		}
		// Skip tombstone entries: these are deleted issues exported by older
		// versions (pre-v0.50) with status "tombstone" and deleted_at set.
		// They are not valid for re-import since "tombstone" is not a real status.
		if issue.Status == "tombstone" {
			continue

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped json.Unmarshal error — it names the offending field and expected type; fix that line's field types.
  2. Compare against a known-good memory line from a `bd export` and correct your record to match the schema.
  3. Ensure the exporting and importing bd versions match; re-export with the current version if schemas differ.
  4. Remove the bad memory line if the memory is unnecessary, and import the issues separately.

Example fix

// before
{"_type":"memory","key":"foo","value":123}        # value not a string
// after
{"_type":"memory","key":"foo","value":"123"}    # string value matches memoryRecord
Defensive patterns

Strategy: type-guard

Validate before calling

func validateMemoryLines(path string) error {
    data, _ := os.ReadFile(path)
    for i, line := range strings.Split(string(data), "\n") {
        var peek map[string]json.RawMessage
        if json.Unmarshal([]byte(line), &peek) != nil { continue }
        if t, ok := peek["_type"]; ok && string(t) == `"memory"` {
            var mem struct {
                Key   string `json:"key"`
                Value string `json:"value"`
            }
            if err := json.Unmarshal([]byte(line), &mem); err != nil {
                return fmt.Errorf("line %d: %w", i+1, err)
            }
        }
    }
    return nil
}

Type guard

func isMemoryRecord(line []byte) (memoryRecord, bool) {
    var peek map[string]json.RawMessage
    if json.Unmarshal(line, &peek) != nil { return memoryRecord{}, false }
    if t, ok := peek["_type"]; !ok || string(t) != `"memory"` { return memoryRecord{}, false }
    var mem memoryRecord
    if json.Unmarshal(line, &mem) != nil { return memoryRecord{}, false }
    return mem, true
}

Try / catch

if err := importFrom(path); err != nil {
    if strings.Contains(err.Error(), "failed to parse memory record") {
        return fmt.Errorf("memory line field types don't match schema; fix or drop the line: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: `bd import file.jsonl` containing a line like {"_type":"memory",...} whose fields have incompatible types (e.g. `key` as a number, nested object where a string is expected) or missing required JSON structure for memoryRecord.

Common situations: Hand-crafted memory records with wrong field types; exports from a newer/older bd version with a changed memory schema imported by a mismatched binary; scripts generating memory lines programmatically with unquoted or numeric values.

Understand the failure class

Related errors


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