henrygd/beszel · error

failed to delete from %s: %v

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.

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)

Solutions

  1. Check the wrapped error (%v) for the SQLite/dxdb root cause (locked, disk full, no such table)
  2. Verify the stats collections still exist with the expected names in the PocketBase schema
  3. 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

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


AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31). Data as JSON: /api/errors/4144a1e0e1c8054f. Report an issue: GitHub.