moghtech/komodo · critical · anyhow::Error

Finished backing up database with errors 🚨

Error message

Finished backing up database with errors 🚨

What it means

backup streams the database to a backup while recording per-item failures in an atomic has_error flag. At the end, if any error occurred during the run, it returns this error instead of logging success — the backup file may be produced but is incomplete or partially failed.

Solutions

  1. Scan preceding logs for the per-item errors logged during the backup — they name the actual cause
  2. Check disk space and write permissions on the backup destination directory
  3. Fix or exclude the corrupted/failing records reported, then rerun the backup
  4. Alert/monitor: a backup ending with this error must not be treated as a good backup
Defensive patterns

Strategy: validation

Validate before calling

let meta = fs::metadata(&backup_dir).context("backup dir")?;
anyhow::ensure!(meta.permissions().mode() & 0o200 != 0, "backup dir not writable");
anyhow::ensure!(fs2::free_space(&backup_dir)? > required_bytes, "insufficient disk space for backup");

Try / catch

match backup(config).await {
    Ok(()) => info!("backup OK"),
    Err(e) if e.to_string().contains("with errors") => {
        error!("backup incomplete — do not ship this file; inspect prior per-item errors");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Any individual document/collection failing to serialize or write during backup (disk full, permission denied on backup path, unreadable DB entries) sets has_error; backup() then finishes with this error.

Common situations: Backup directory without write permission, disk quota/full disk, corrupted database entries, race with concurrent writes during backup.

Related errors


AI-assisted analysis of moghtech/komodo@780ac68b99 (2026-09-08). Data as JSON: /api/errors/f4200cdb66491d9c. Report an issue: GitHub.

Appendix: source

Thrown at lib/database/src/utils/backup.rs:138

            has_error.store(true, atomic::Ordering::Relaxed);
          }
        }
      })
    })
    .collect::<FuturesUnordered<_>>();

  loop {
    match handles.next().await {
      Some(Ok(())) => {}
      Some(Err(e)) => {
        error!("{e:#}");
      }
      None => break,
    }
  }

  if has_error.load(atomic::Ordering::Relaxed) {
    Err(anyhow!("Finished backing up database with errors 🚨"))
  } else {
    info!("Finished backing up database ✅");
    Ok(())
  }
}

View on GitHub (pinned to 780ac68b99)