amir20/dozzle · error

failed to compile event expression

Error message

failed to compile event expression: %w

What it means

UpdateSubscription compiles a new event expression with expr-lang before storing it. If the expression string is syntactically invalid or references fields/methods that don't exist on types.NotificationEvent, the compile fails and the underlying expr error is wrapped with this message, aborting the update via xsync.CancelOp (no partial mutation).

Solutions

  1. Check the wrapped expr error: it names the exact token/position that failed to parse
  2. Validate the expression against types.NotificationEvent fields and use only those identifiers
  3. Test the expression in an expr playground or with expr.Compile(exprStr, expr.Env(types.NotificationEvent{})) in a scratch test before calling UpdateSubscription
  4. Fix quoting/escaping if the expression was pasted from YAML or JSON where quotes were consumed

Example fix

// before
UpdateSubscription(1, map[string]any{"eventExpression": "event.level == 'error' && event.container == 'web"}) // unterminated string
// after
UpdateSubscription(1, map[string]any{"eventExpression": "event.Level == 'error' && event.ContainerName == 'web'"})
Defensive patterns

Strategy: validation

Validate before calling

func validEventExpr(s string) bool {
    _, err := expr.Compile(s, expr.Env(types.NotificationEvent{}))
    return s != "" && err == nil
}

Try / catch

if err := manager.UpdateSubscription(id, updates); err != nil {
    var cerr interface{ Unwrap() error }
    // log err; surface the wrapped expr compile error to the user
}

Prevention

When it happens

Trigger: Calling UpdateSubscription with updates containing a non-empty eventExpression string that expr.Compile rejects: bad syntax (e.g. unbalanced parens), unknown identifiers (fields not on NotificationEvent), or wrong types in comparisons.

Common situations: Hand-editing notifications.yml and pasting the expression into the API/UI; typos in field names like event.Name vs event.ContainerName; using functions unavailable in the expr environment; frontend sending an expression built for a different event shape.

Related errors


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

Appendix: source

Thrown at internal/notification/manager.go:233

					if exprStr != "" {
						program, err := expr.Compile(exprStr, expr.Env(types.NotificationStat{}))
						if err != nil {
							updateErr = fmt.Errorf("failed to compile metric expression: %w", err)
							return nil, xsync.CancelOp
						}
						updated.MetricExpression = exprStr
						updated.MetricProgram = program
					} else {
						updated.MetricExpression = ""
						updated.MetricProgram = nil
					}
				}
			case "eventExpression":
				if exprStr, ok := value.(string); ok {
					if exprStr != "" {
						program, err := expr.Compile(exprStr, expr.Env(types.NotificationEvent{}))
						if err != nil {
							updateErr = fmt.Errorf("failed to compile event expression: %w", err)
							return nil, xsync.CancelOp
						}
						updated.EventExpression = exprStr
						updated.EventProgram = program
					} else {
						updated.EventExpression = ""
						updated.EventProgram = nil
					}
				}
			case "cooldown":
				if cd, ok := value.(int); ok {
					updated.Cooldown = cd
				}
			case "sampleWindow":
				if sw, ok := value.(int); ok {
					updated.SampleWindow = sw
					updated.MetricSampleBuffers = xsync.NewMap[string, *utils.RingBuffer[bool]]()
				}

View on GitHub (pinned to d9463cbe21)