{"record":{"id":"430133eaa8a0b12e","repo":"gastownhall/beads","slug":"storage-backend-does-not-support-backup-operations-430133","errorCode":null,"errorMessage":"storage backend does not support backup operations","messagePattern":"storage backend does not support backup operations","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/backup_export.go","lineNumber":152,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Change detection: skip if nothing changed (unless forced)\n\tif !force {\n\t\tcurrentCommit, err := store.GetCurrentCommit(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get current commit: %w\", err)\n\t\t}\n\t\tif currentCommit == state.LastDoltCommit && state.LastDoltCommit != \"\" {\n\t\t\tdebug.Logf(\"backup: no changes since last backup (commit %s)\\n\", truncateHash(currentCommit))\n\t\t\treturn state, nil\n\t\t}\n\t}\n\n\tbs, ok := storage.UnwrapStore(store).(storage.BackupStore)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"storage backend does not support backup operations\")\n\t}\n\n\tif err := bs.BackupDatabase(ctx, dir); err != nil {\n\t\t// Persist the attempt time even on failure so the throttle\n\t\t// interval (checked by maybeAutoBackup via state.Timestamp)\n\t\t// applies to the next command. Without this, a sync that keeps\n\t\t// failing — e.g. a slow/overloaded shared Dolt server — retries\n\t\t// on EVERY bd command instead of once per interval, turning a\n\t\t// transient slowdown into a self-amplifying storm (the 2026-07\n\t\t// shared-dolt CPU-pin incident). LastDoltCommit is deliberately\n\t\t// left unchanged so change-detection still sees pending work and\n\t\t// a real backup runs once the failure clears.\n\t\tstate.Timestamp = time.Now().UTC()\n\t\tif saveErr := saveBackupState(dir, state); saveErr != nil {\n\t\t\tdebug.Logf(\"backup: failed to persist throttle state after error: %v\\n\", saveErr)\n\t\t}\n\t\treturn nil, err\n\t}","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/backup_export.go#L134-L170","documentation":"runBackupExport requires the unwrapped store to implement storage.BackupStore. storage.UnwrapStore(store) peels proxy/wrapper layers, and if the concrete backend does not implement BackupDatabase, backup cannot proceed. The Dolt backend supports backups; simpler backends (e.g. JSON-file storage) do not.","triggerScenarios":"Auto-backup (maybeAutoBackup) or backup export runs against a storage backend that lacks BackupDatabase — i.e., the workspace is not using Dolt storage.","commonSituations":"Legacy workspace still on JSON issue storage (.beads/issues.jsonl) instead of Dolt; custom/embedded storage drivers without backup support; mismatched bd build using a reduced backend.","solutions":["Check your storage backend (bd doctor or presence of .beads/dolt/) — backups require Dolt storage.","Migrate the workspace to Dolt storage if on legacy JSON (follow bd's migration/import path), then retry.","Skip auto-backup expectations for non-Dolt backends: back up the storage files yourself (e.g. copy .beads/issues.jsonl).","If you believe your backend should support backups, verify you're on a recent bd version and file an issue."],"exampleFix":"// check backend\nls .beads/dolt 2>/dev/null && echo dolt || echo non-dolt\n// non-dolt fallback\n# disable/ignore auto-backup and back up storage files manually\ncp -f .beads/issues.jsonl ~/backups/issues-$(date +%F).jsonl","handlingStrategy":"type-guard","validationCode":"// confirm Dolt-backed storage before attempting backup flows\nif _, err := os.Stat(\".beads/dolt\"); err != nil {\n    log.Println(\"workspace is not Dolt-backed; BackupStore operations unavailable\")\n}","typeGuard":"bs, ok := storage.UnwrapStore(store).(storage.BackupStore)\nif !ok {\n    // backend does not support backups; skip auto-backup instead of erroring\n    return nil\n}","tryCatchPattern":"if err := maybeAutoBackup(ctx, store, dir); err != nil {\n    if strings.Contains(err.Error(), \"does not support backup operations\") {\n        log.Println(\"non-Dolt backend: skipping built-in backup; back up storage files manually\")\n        return nil\n    }\n    return err\n}","preventionTips":["Migrate legacy JSON workspaces to Dolt storage to get built-in backups","Gate auto-backup on backend capability instead of assuming Dolt","For non-Dolt backends, schedule your own file-level backups of .beads"],"tags":["go","storage","dolt","unsupported-operation","backup"],"backgroundTag":"unsupported-storage-backend","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}