henrygd/beszel · error
failed to delete from
Error message
failed to delete from %s: %v
What it means
deleteOldSystemStats builds a raw DELETE query per stats collection with OR-joined time conditions and executes it against the PocketBase DB. If execution fails, the collection name is embedded in this error so the failing table is identified.
Solutions
- Check the wrapped error (%v) for the SQLite/dxdb root cause (locked, disk full, no such table)
- Verify the stats collections still exist with the expected names in the PocketBase schema
- Check disk space and that no backup/other process holds an exclusive lock on the DB during cleanup
Example fix
// before
rawQuery := fmt.Sprintf("DELETE FROM %s WHERE %s", collection, conditionStr)
// after
// ensure collection exists and log the underlying error
if _, err := app.DB().NewQuery(rawQuery).Bind(params).Execute(); err != nil {
return fmt.Errorf("failed to delete from %s: %w", collection, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if !collectionExists(app, collection) {
return fmt.Errorf("stats collection %s missing from schema", collection)
}
if diskAlmostFull() { return errors.New("insufficient disk space for retention cleanup") } Try / catch
if err := records.DeleteOldSystemStats(app); err != nil {
log.Error().Err(err).Msg("system stats retention cleanup failed")
// alert/check DB lock and disk space; retry next cycle
} Prevention
- Monitor disk space on the hub host
- Avoid exclusive DB locks (backups) during cleanup windows
- Verify stats collection names after schema migrations
- Alert on retention-cleanup failures
When it happens
Trigger: DB-level failure executing the raw DELETE on a system_stats collection: locked database, disk full, permission issues, or a collection name that no longer exists in the schema.
Common situations: SQLite file locked by another process/backup job; disk quota exceeded on the host; schema migrations renaming/dropping a stats collection while retention cleanup still references it.
Related errors
- failed to delete old container records
- failed to delete old systemd service records
- failed to create new system
- failed to find systems collection
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/4144a1e0e1c8054f.
Report an issue: GitHub.
Appendix: source
Thrown at internal/records/records_deletion.go:96
now := time.Now().UTC()
for _, collection := range collections {
// Build the WHERE clause
var conditionParts []string
var params dbx.Params = make(map[string]any)
for i := range recordData {
rd := recordData[i]
// Create parameterized condition for this record type
dateParam := fmt.Sprintf("date%d", i)
conditionParts = append(conditionParts, fmt.Sprintf("(type = '%s' AND created < {:%s})", rd.recordType, dateParam))
params[dateParam] = now.Add(-rd.retention)
}
// Combine conditions with OR
conditionStr := strings.Join(conditionParts, " OR ")
// Construct and execute the full raw query
rawQuery := fmt.Sprintf("DELETE FROM %s WHERE %s", collection, conditionStr)
if _, err := app.DB().NewQuery(rawQuery).Bind(params).Execute(); err != nil {
return fmt.Errorf("failed to delete from %s: %v", collection, err)
}
}
return nil
}
// Deletes systemd service records that haven't been updated in the last 20 minutes
func deleteOldSystemdServiceRecords(app core.App) error {
now := time.Now().UTC()
twentyMinutesAgo := now.Add(-20 * time.Minute)
// Delete systemd service records where updated < twentyMinutesAgo
_, err := app.DB().NewQuery("DELETE FROM systemd_services WHERE updated < {:updated}").Bind(dbx.Params{"updated": twentyMinutesAgo.UnixMilli()}).Execute()
if err != nil {
return fmt.Errorf("failed to delete old systemd service records: %v", err)
}
return nil
}View on GitHub (pinned to b38fb7dafa)