gastownhall/beads · error
failed to marshal issue %s: %w
Error message
failed to marshal issue %s: %w
What it means
While writing the backup, each polluted issue is serialized with json.Marshal before being appended as a JSONL line. If marshaling a particular issue fails, backupPollutedIssues returns this error naming the issue ID. With standard issue structs this is rare and usually indicates an unsupported value embedded in the issue (e.g. a channel, func, or cyclic field).
Source
Thrown at cmd/bd/detect_pollution.go:112
}
return results
}
func backupPollutedIssues(polluted []pollutionResult, path string) error {
// Create backup file
// nolint:gosec // G304: path is provided by user as explicit backup location
file, err := os.Create(path)
if err != nil {
return fmt.Errorf("failed to create backup file: %w", err)
}
defer file.Close()
// Write each issue as JSONL
for _, p := range polluted {
data, err := json.Marshal(p.issue)
if err != nil {
return fmt.Errorf("failed to marshal issue %s: %w", p.issue.ID, err)
}
if _, err := file.WriteString(string(data) + "\n"); err != nil {
return fmt.Errorf("failed to write issue %s: %w", p.issue.ID, err)
}
}
return nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Identify the offending issue ID from the message and inspect it with 'bd show <id>' or direct DB access.
- Fix or remove the malformed issue so it can be serialized (edit and re-save it).
- Check for schema/version mismatch between the bd binary and the database; upgrade or run migration.
- If caused by a code change to types.Issue, add a MarshalJSON or json tag fix for the unsupported field.
Example fix
// before: unsupported field Custom chan int `json:"custom"` // after: remove or give it a JSON-safe representation Custom string `json:"custom,omitempty"`
Defensive patterns
Strategy: validation
Validate before calling
// probe-serialize issues before committing to the backup run
for _, p := range polluted {
if _, err := json.Marshal(p.issue); err != nil {
fmt.Printf("issue %s will fail backup: %v\n", p.issue.ID, err)
}
} Try / catch
if _, err := json.Marshal(p.issue); err != nil {
log.Printf("skipping unmarshalable issue %s: %v", p.issue.ID, err)
continue
} Prevention
- Keep types.Issue fields JSON-serializable (no chan/func/cyclic fields).
- Add json tags to all exported struct fields.
- Fix or quarantine malformed issues flagged by doctor before backup.
- Keep the bd binary and database schema versions aligned.
When it happens
Trigger: os.Create succeeded but json.Marshal(p.issue) returns an error for a specific issue — typically a corrupted or non-serializable field in the stored issue data, or a struct field type unsupported by encoding/json.
Common situations: Database contains an issue written by an older/incompatible schema whose fields no longer marshal; custom field values inserted directly into storage; third-party types lacking MarshalJSON injected into the issue struct.
Related errors
- failed to marshal backup state: %w
- failed to parse backup state: %w
- failed to marshal interactions log entry: %w
- marshal create request: %w
- serializing waits-for metadata: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/61b1516e3949e2c0.
Report an issue: GitHub.