amir20/dozzle · error

failed to compile container expression

Error message

failed to compile container expression: %w

What it means

Subscription.CompileExpressions compiles ContainerExpression with expr against the types.NotificationContainer environment. An invalid expression (syntax error or unknown identifier) aborts compilation and returns a wrapped error naming which expression failed; the subscription is left unusable.

Solutions

  1. Read the wrapped expr error for the exact parse position/unknown identifier
  2. Use only fields defined on types.NotificationContainer in the expression
  3. Compile-test the expression in a unit test or expr playground with the NotificationContainer env before persisting
  4. If the field is intentional, add it to types.NotificationContainer so the env exposes it

Example fix

// before
s.ContainerExpression = "container.name == 'web'" // unknown field
// after
s.ContainerExpression = "container.Name == 'web'" // field on types.NotificationContainer
Defensive patterns

Strategy: validation

Validate before calling

func validContainerExpr(s string) error {
    _, err := expr.Compile(s, expr.Env(types.NotificationContainer{}))
    return err
}

Try / catch

sub := types.Subscription{ContainerExpression: expr}
if err := sub.CompileExpressions(); err != nil {
    return fmt.Errorf("rejecting subscription: %w", err)
}

Prevention

When it happens

Trigger: AddSubscription, ReplaceSubscription, loadSubscription, or compiledSub receiving a Subscription whose ContainerExpression is non-empty and rejected by expr.Compile(expr, expr.Env(types.NotificationContainer{})).

Common situations: Hand-edited notifications.yml with a bad container expression; typos like container.name instead of the real field on NotificationContainer; expressions copied from a different subscription type (log/metric) using incompatible fields.

Related errors


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

Appendix: source

Thrown at internal/notification/types.go:175

	}
	return s.TriggeredContainerIDs.Size()
}

// AddTriggeredContainer adds a container ID to the triggered set
func (s *Subscription) AddTriggeredContainer(id string) {
	if s.TriggeredContainerIDs == nil {
		s.TriggeredContainerIDs = xsync.NewMap[string, struct{}]()
	}
	s.TriggeredContainerIDs.Store(id, struct{}{})
}

// CompileExpressions compiles all expression strings into executable programs.
// Returns an error describing which expression failed to compile.
func (s *Subscription) CompileExpressions() error {
	if s.ContainerExpression != "" {
		program, err := expr.Compile(s.ContainerExpression, expr.Env(types.NotificationContainer{}))
		if err != nil {
			return fmt.Errorf("failed to compile container expression: %w", err)
		}
		s.ContainerProgram = program
	}

	if s.LogExpression != "" {
		program, err := expr.Compile(s.LogExpression, expr.Env(types.NotificationLog{}))
		if err != nil {
			return fmt.Errorf("failed to compile log expression: %w", err)
		}
		s.LogProgram = program
	}

	if s.MetricExpression != "" {
		program, err := expr.Compile(s.MetricExpression, expr.Env(types.NotificationStat{}))
		if err != nil {
			return fmt.Errorf("failed to compile metric expression: %w", err)
		}
		s.MetricProgram = program

View on GitHub (pinned to d9463cbe21)