glanceapp/glance · error

service must be one of: %s, %s, %s, %s

Error message

service must be one of: %s, %s, %s, %s

What it means

Returned by dnsStatsWidget.Initialize when widget.Service is not one of the four supported constants: adguard, pihole_v6 (dnsServicePiholeV6), pihole, technitium. It is a pure config-validation error raised at page load before any network activity.

Source

Thrown at internal/glance/widget-dns-stats.go:81

func (widget *dnsStatsWidget) initialize() error {
	titleURL := strings.TrimRight(widget.URL, "/")
	switch widget.Service {
	case dnsServicePihole, dnsServicePiholeV6:
		titleURL = titleURL + "/admin"
	}

	widget.
		withTitle("DNS Stats").
		withTitleURL(titleURL).
		withCacheDuration(10 * time.Minute)

	switch widget.Service {
	case dnsServiceAdguard:
	case dnsServicePiholeV6:
	case dnsServicePihole:
	case dnsServiceTechnitium:
	default:
		return fmt.Errorf("service must be one of: %s, %s, %s, %s", dnsServiceAdguard, dnsServicePihole, dnsServicePiholeV6, dnsServiceTechnitium)
	}

	return nil
}

func (widget *dnsStatsWidget) update(ctx context.Context) {
	var stats *dnsStats
	var err error

	switch widget.Service {
	case dnsServiceAdguard:
		stats, err = fetchAdguardStats(widget.URL, widget.AllowInsecure, widget.Username, widget.Password, widget.HideGraph)
	case dnsServicePihole:
		stats, err = fetchPihole5Stats(widget.URL, widget.AllowInsecure, widget.Token, widget.HideGraph)
	case dnsServiceTechnitium:
		stats, err = fetchTechnitiumStats(widget.URL, widget.AllowInsecure, widget.Token, widget.HideGraph)
	case dnsServicePiholeV6:
		var newSessionID string

View on GitHub (pinned to 91324e8de7)

Solutions

  1. Set service to exactly one of: adguard, pihole, pihole_v6, technitium (lowercase).
  2. Check YAML indentation — service: must sit under the dns-stats widget, not a sibling key.
  3. After editing, reload the page/config; the error appears immediately on render.

Example fix

# before
- type: dns-stats
  service: adguard-home

# after
- type: dns-stats
  service: adguard
Defensive patterns

Strategy: validation

Validate before calling

var validDNSServices = map[string]bool{
    "adguard": true, "pihole": true, "pihole_v6": true, "technitium": true,
}
if !validDNSServices[widget.Service] {
    return fmt.Errorf("dns-stats: service must be one of adguard, pihole, pihole_v6, technitium, got %q", widget.Service)
}

Prevention

When it happens

Trigger: Setting service: adguard-home, service: PiHole, service: nextdns, or omitting/changing the key in a dns-stats widget block.

Common situations: Guessing the service name instead of copying the docs; case mismatch; renaming after upgrading glance versions that changed accepted values.

Related errors


AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15). Data as JSON: /api/errors/ad18bb62d313ec9f. Report an issue: GitHub.