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" {
continueView on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped json.Unmarshal error — it names the offending field and expected type; fix that line's field types.
- Compare against a known-good memory line from a `bd export` and correct your record to match the schema.
- Ensure the exporting and importing bd versions match; re-export with the current version if schemas differ.
- 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
- Quote all memory record string fields in hand-written JSONL.
- Keep exporting and importing bd versions in sync (schema changes).
- Generate memory lines from a reference `bd export` instead of from scratch.
- Pre-validate `_type:"memory"` lines with a struct unmarshal before import.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse memory record: %w
- failed to parse issue from JSONL: %w
- failed to parse JSONL line: %w
- failed to parse issues response: %w
- failed to parse team states response: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a3c1fc9832e8a19b.
Report an issue: GitHub.