amir20/dozzle · error

unknown dispatcher type

Error message

unknown dispatcher type: %s

What it means

createDispatcher switches on DispatcherConfig.Type and returns this error when the type string matches no registered dispatcher factory (webhook, etc.). Cloud types are intentionally not created here, so a cloud-typed or misspelled type in notifications.yml reaches this guard.

Solutions

  1. Use a supported type such as 'webhook' (see dispatcher factory registrations).
  2. Fix typos in the type field of notifications.yml.
  3. Remove cloud-type dispatcher entries from notifications.yml; cloud dispatchers are managed via cloud.yml.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at internal/notification/config.go:205 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/a735d7a7ff945b13. Report an issue: GitHub.

Appendix: source

Thrown at internal/notification/config.go:205

		}
		m.dispatchers.Store(dc.ID, d)
		log.Debug().Int("id", dc.ID).Msg("Loaded dispatcher from state sync")
	}

	m.updateListeners()

	log.Debug().Int("subscriptions", len(subscriptions)).Int("dispatchers", len(dispatchers)).Msg("Replaced notification state")
	return nil
}

// createDispatcher creates a dispatcher from a DispatcherConfig.
// Cloud dispatchers are not created here; they are managed via cloud.yml and SetCloudDispatcher.
func createDispatcher(config DispatcherConfig) (dispatcher.Dispatcher, error) {
	switch config.Type {
	case "webhook":
		return dispatcher.NewWebhookDispatcher(config.Name, config.URL, config.Template, config.Headers)
	default:
		return nil, fmt.Errorf("unknown dispatcher type: %s", config.Type)
	}
}

// loadSubscription loads a subscription with its existing ID (used when loading from config)
func (m *Manager) loadSubscription(sub *Subscription) error {
	if err := sub.CompileExpressions(); err != nil {
		return err
	}

	if sub.MetricCooldowns == nil {
		sub.MetricCooldowns = xsync.NewMap[string, time.Time]()
	}
	if sub.MetricSampleBuffers == nil {
		sub.MetricSampleBuffers = xsync.NewMap[string, *utils.RingBuffer[bool]]()
	}
	if sub.EventCooldowns == nil {
		sub.EventCooldowns = xsync.NewMap[string, time.Time]()
	}

View on GitHub (pinned to d9463cbe21)