gastownhall/beads · error
import memory %q: %w
Error message
import memory %q: %w
What it means
While landing the import batch inside the unit of work, each memory record is written via the config use case (SetConfig). If that write fails, the error is wrapped with the offending memory key as "import memory %q". The whole batch transaction then aborts and rolls back, so nothing from the batch is committed.
Source
Thrown at internal/storage/uow/importer.go:95
})
},
OnStaleRejected: func(issueID string) {
if _, ok := staleRejected[issueID]; ok {
return
}
staleRejected[issueID] = struct{}{}
result.StaleRejectedIDs = append(result.StaleRejectedIDs, issueID)
},
}
if _, err := storageissueops.CreateIssuesInTxWithResult(ctx, runner, request.Issues, request.Actor, opts); err != nil {
return publicops.ImportBatchResult{}, "", err
}
result.Created = len(request.Issues) - len(staleRejected)
}
for _, memory := range request.Memories {
if err := uw.ConfigUseCase().SetConfig(ctx, memory.Key, memory.Value); err != nil {
return publicops.ImportBatchResult{}, "", fmt.Errorf("import memory %q: %w", memory.Key, err)
}
result.MemoriesImported++
}
// config.yaml is authoritative for issue_prefix on the import flow
// (be-llaf); a read or write failure here degrades to "not synced"
// rather than failing the batch, matching the classic path.
if request.SyncIssuePrefix != "" {
stored, _ := uw.ConfigUseCase().GetConfig(ctx, "issue_prefix")
if stored != request.SyncIssuePrefix {
if err := uw.ConfigUseCase().SetConfig(ctx, "issue_prefix", request.SyncIssuePrefix); err == nil {
result.PrefixSynced = true
}
}
}
return result, importBatchCommitMessage(request, result), nil
})View on GitHub (pinned to 71377f2769)
Solutions
- Sanitize memory entries before import: skip or fix entries with empty/invalid keys.
- Retry the import after confirming DB connectivity if the wrapped error is a connection/serialization failure (RunTxResult already retries serialization, but hard I/O errors are not retried).
- Inspect the wrapped inner error for the root cause — it names the exact SetConfig failure.
- Update the failing key's value or drop the record from the import source, then re-run; the batch is atomic so no partial state needs cleanup.
Example fix
// before
for _, m := range rawMemories {
request.Memories = append(request.Memories, publicops.MemoryEntry{Key: m.Key, Value: m.Value}) // m.Key may be ""
}
// after
for _, m := range rawMemories {
if m.Key == "" {
log.Printf("skipping memory with empty key")
continue
}
request.Memories = append(request.Memories, publicops.MemoryEntry{Key: m.Key, Value: m.Value})
} Defensive patterns
Strategy: try-catch
Validate before calling
for i, m := range request.Memories {
if strings.TrimSpace(m.Key) == "" {
return fmt.Errorf("memory entry %d has empty key", i)
}
} Type guard
func validMemories(ms []publicops.MemoryEntry) bool {
for _, m := range ms {
if m.Key == "" {
return false
}
}
return true
} Try / catch
result, err := imp.ImportBatch(ctx, req)
if err != nil {
var key string
if n, serr := fmt.Sscanf(err.Error(), "import memory %q:", &key); serr == nil && n == 1 {
return fmt.Errorf("import aborted at memory %q (batch rolled back): %w", key, err)
}
return err
} Prevention
- Sanitize/skip empty or malformed memory keys when building the request from import files.
- Treat imports as all-or-nothing: no partial state persists, so re-running is safe after fixing data.
- Verify DB connectivity before large imports to avoid mid-transaction SetConfig failures.
- Coordinate concurrent bd sync processes so the same config keys aren't written simultaneously.
When it happens
Trigger: Calling ImportBatch with request.Memories whose Key cannot be written by uw.ConfigUseCase().SetConfig — e.g. an empty or invalid key, a key colliding with protected config, storage-layer failures (connection dropped mid-tx), or a duplicate write conflict inside the transaction.
Common situations: Import files (JSONL) containing malformed memory entries with empty keys or control characters; concurrent `bd` processes writing the same config key during sync; database connectivity loss partway through a large import.
Related errors
- load create context: %w
- graph create: %w
- reading gate %s: %w
- batch create: %w
- node %q: updating metadata refs: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/41fa6bea010c5e25.
Report an issue: GitHub.