glanceapp/glance · error

unknown widget type

Error message

unknown widget type: %s

What it means

newWidget() fell through its type switch: the string in a widget block's type field matches no supported widget type. The listed value is echoed back so the typo is identifiable directly from the error.

Solutions

  1. Compare the echoed type against the widget names in the switch statement in internal/glance/widget.go or the docs
  2. Fix the spelling/casing in glance.yml — values are lowercase-hyphenated
  3. If the widget was renamed across versions, update the config to the new name from the changelog

Example fix

# before
- type: wether

# after
- type: weather
Defensive patterns

Strategy: validation

Validate before calling

// Validate widget types against the known set before starting Glance
var knownWidgetTypes = map[string]bool{
    "weather": true, "videos": true, "twitch-channels": true /* ... full list from widget.go */,
}

func validWidgetType(t string) bool { return knownWidgetTypes[t] }

Type guard

func isUnknownWidgetType(err error) bool {
	return err != nil && strings.HasPrefix(err.Error(), "unknown widget type")
}

Try / catch

w, err := newWidget(cfg.Type)
if isUnknownWidgetType(err) {
    // fail config validation with the offending type name; do not silently skip
    return fmt.Errorf("page %q: %w", pageName, err)
}

Prevention

When it happens

Trigger: A glance.yml page containing a widget whose type is misspelled ('wether'), uses a legacy name removed in a version upgrade, or references a widget compiled out of the build.

Common situations: Typos; upgrading Glance and a widget was renamed (config from an older release); community configs referencing custom widget builds.

Related errors


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

Appendix: source

Thrown at internal/glance/widget.go:85

		w = &searchWidget{}
	case "extension":
		w = &extensionWidget{}
	case "group":
		w = &groupWidget{}
	case "dns-stats":
		w = &dnsStatsWidget{}
	case "split-column":
		w = &splitColumnWidget{}
	case "custom-api":
		w = &customAPIWidget{}
	case "docker-containers":
		w = &dockerContainersWidget{}
	case "server-stats":
		w = &serverStatsWidget{}
	case "to-do":
		w = &todoWidget{}
	default:
		return nil, fmt.Errorf("unknown widget type: %s", widgetType)
	}

	w.setID(widgetIDCounter.Add(1))

	return w, nil
}

type widgets []widget

func (w *widgets) UnmarshalYAML(node *yaml.Node) error {
	var nodes []yaml.Node

	if err := node.Decode(&nodes); err != nil {
		return err
	}

	for _, node := range nodes {
		meta := struct {

View on GitHub (pinned to 91324e8de7)