amir20/dozzle · error

failed to compile container expression

Error message

failed to compile container expression: %w

What it means

When UpdateSubscription receives a "containerExpression" field, it compiles the string with the expr-lang expression compiler against the types.NotificationContainer environment before accepting it. This error wraps expr.Compile failures: syntax errors, unknown identifiers/functions, or type-incorrect operations for that environment. The update is cancelled and the subscription is left unchanged.

Solutions

  1. Read the wrapped expr.Compile error, which names the exact syntax/type problem and position.
  2. Restrict the expression to fields defined on types.NotificationContainer (check the struct definition).
  3. Validate the expression in the UI (or a scratch expr run) before calling UpdateSubscription.

Example fix

// before (field not on NotificationContainer)
updates := map[string]any{"containerExpression": "log.Level == 'error'"}
// after
updates := map[string]any{"containerExpression": "container.Name == \"nginx\""}
Defensive patterns

Strategy: validation

Validate before calling

if exprStr, ok := updates["containerExpression"].(string); ok {
    if _, err := expr.Compile(exprStr, expr.Env(types.NotificationContainer{})); err != nil {
        return fmt.Errorf("invalid containerExpression: %w", err)
    }
}

Try / catch

if err := manager.UpdateSubscription(id, updates); err != nil {
    var ce *expr.Error
    if errors.As(err, &ce) {
        return fmt.Errorf("expression error at offset %d: %v", ce.Offset, ce)
    }
    return err
}

Prevention

When it happens

Trigger: Submitting an update map with key "containerExpression" set to a string that is not a valid expr program over NotificationContainer, e.g. a wrong field name, unbalanced parentheses, or comparing incompatible types.

Common situations: Users hand-writing container filter expressions in the alert UI with typos (continer.Name), using fields that belong to NotificationLog instead, or copying expressions from another tool with different syntax.

Related errors


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

Appendix: source

Thrown at internal/notification/manager.go:192

		for key, value := range updates {
			switch key {
			case "name":
				if name, ok := value.(string); ok {
					updated.Name = name
				}
			case "enabled":
				if enabled, ok := value.(bool); ok {
					updated.Enabled = enabled
				}
			case "dispatcherId":
				if dispatcherID, ok := value.(int); ok {
					updated.DispatcherID = dispatcherID
				}
			case "containerExpression":
				if exprStr, ok := value.(string); ok {
					program, err := expr.Compile(exprStr, expr.Env(types.NotificationContainer{}))
					if err != nil {
						updateErr = fmt.Errorf("failed to compile container expression: %w", err)
						return nil, xsync.CancelOp
					}
					updated.ContainerExpression = exprStr
					updated.ContainerProgram = program
				}
			case "logExpression":
				if exprStr, ok := value.(string); ok {
					if exprStr != "" {
						program, err := expr.Compile(exprStr, expr.Env(types.NotificationLog{}))
						if err != nil {
							updateErr = fmt.Errorf("failed to compile log expression: %w", err)
							return nil, xsync.CancelOp
						}
						updated.LogExpression = exprStr
						updated.LogProgram = program
					} else {
						updated.LogExpression = ""
						updated.LogProgram = nil

View on GitHub (pinned to d9463cbe21)