gastownhall/beads · error

auto-export shrink guard: refusing to overwrite %s because i

Error message

auto-export shrink guard: refusing to overwrite %s because it contains %d record(s) outside auto-export scope (%d memories, %d infra/template/ephemeral issues, %d unknown); run an explicit export if you want to replace it

What it means

The auto-export shrink guard refuses to overwrite the JSONL when it contains records outside auto-export scope: memories (when not included), infra/template/ephemeral issues still present in the store (GH#4069), or unknown record types. Overwriting would silently drop those records, so bd aborts and asks for an explicit export instead.

Source

Thrown at cmd/bd/export_auto.go:746

			continue
		}
		if err := classifyExistingAutoExportRecord([]byte(line), infraTypes, includeMemories, storeIDs, &stats); err != nil {
			return fmt.Errorf("auto-export shrink guard: inspect existing JSONL line %d: %w", lineNo, err)
		}
	}
	if err := scanner.Err(); err != nil {
		return fmt.Errorf("auto-export shrink guard: inspect existing JSONL: %w", err)
	}

	// Store-presence rule (#4069 vs #4988): block on memories (when
	// excluded), unknown record types, and out-of-scope issue rows whose id
	// is STILL present in the store — those are exactly what #4069 says we
	// must not silently drop. An out-of-scope row absent from the store
	// (e.g. a TTL-compacted wisp) is safe to drop and does not block.
	if stats.FilteredRecords == 0 {
		return nil
	}
	return fmt.Errorf("auto-export shrink guard: refusing to overwrite %s because it contains %d record(s) outside auto-export scope (%d memories, %d infra/template/ephemeral issues, %d unknown); run an explicit export if you want to replace it", path, stats.FilteredRecords, stats.Memories, stats.FilteredIssues, stats.UnknownRecords)
}

type autoExportOverwriteStats struct {
	FilteredRecords int // blocking total: Memories + FilteredIssues + UnknownRecords
	Memories        int
	FilteredIssues  int // infra/template/ephemeral issues still present in the store — blocking (restores GH#4069)
	UnknownRecords  int
}

func classifyExistingAutoExportRecord(line []byte, infraTypes map[string]bool, includeMemories bool, storeIDs map[string]struct{}, stats *autoExportOverwriteStats) error {
	var record struct {
		Type       string          `json:"_type"`
		IssueType  types.IssueType `json:"issue_type"`
		IsTemplate bool            `json:"is_template"`
		Ephemeral  bool            `json:"ephemeral"`
		ID         string          `json:"id"`
	}
	if err := json.Unmarshal(line, &record); err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run an explicit full export (`bd export -o .beads/issues.jsonl`) if you genuinely want to replace the file
  2. Include memories in the export config if the memories in the file are wanted
  3. Clean up or export the out-of-scope issues (infra/template/ephemeral) so the file matches auto-export scope
  4. Check the file for hand-added/unknown records and remove or migrate them

Example fix

// before
// auto-export blocked: refusing to overwrite .beads/issues.jsonl (5 records outside scope...)
// after
bd export -o .beads/issues.jsonl   # explicit export intentionally replaces the file
Defensive patterns

Strategy: validation

Validate before calling

// Check the JSONL for out-of-scope records before exporting
classify := func(line []byte) bool { var r map[string]any; return json.Unmarshal(line, &r) == nil }
f, _ := os.Open(".beads/issues.jsonl")
scanner := bufio.NewScanner(f)
for scanner.Scan() {
    var rec map[string]any
    if json.Unmarshal(scanner.Bytes(), &rec) != nil { fmt.Println("unknown record present") }
    if rec["type"] == "memory" { fmt.Println("memory record present — include memories or export explicitly") }
}

Try / catch

if err := autoExport(); err != nil && strings.Contains(err.Error(), "refusing to overwrite") {
    // Intentional replacement requires explicit export
    runCmd("bd", "export", "-o", ".beads/issues.jsonl")
}

Prevention

When it happens

Trigger: guardAutoExportOverwrite returns this when stats.FilteredRecords > 0 after scanning the existing file — e.g. the file has memories but the export config excludes memories, or it contains infra/template/ephemeral issue rows whose IDs are still in the store, or unrecognized record lines.

Common situations: A repo previously synced with memories included now exports with memories excluded; issues were flipped to type template/ephemeral but still exist in the store; a hand-edited or older-format JSONL has record types the current bd doesn't recognize.

Related errors


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