amir20/dozzle · error

failed to compile log expression

Error message

failed to compile log expression: %w

What it means

For a non-empty "logExpression" update, Manager.UpdateSubscription compiles the string with expr against the types.NotificationLog environment. Failures (syntax errors, unknown fields/functions, type mismatches) are wrapped in this error and the update is cancelled, leaving the existing log expression intact.

Solutions

  1. Check the wrapped expr error for the failing token/position and fix the syntax.
  2. Use only NotificationLog fields (message, level, etc.) in the expression.
  3. An empty string is the supported way to clear the expression; don't pass placeholder text like "none".
  4. Pre-validate the expression with expr.Compile(expr.Env(types.NotificationLog{})) in tests or the UI.

Example fix

// before (unknown field)
{"logExpression": "msg contains 'timeout'"}
// after
{"logExpression": "message contains \"timeout\""}
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

if err := manager.UpdateSubscription(id, updates); err != nil {
    if strings.Contains(err.Error(), "failed to compile log expression") {
        return fmt.Errorf("fix log expression against NotificationLog fields: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Updating a subscription with "logExpression" containing invalid expr syntax or fields not present on NotificationLog (e.g. referencing container-only fields, misspelled message/level keys), including empty-range or unbalanced constructs.

Common situations: Writing log matchers with the wrong field names or Go-side syntax, pasting regexes into expr context without proper quoting, or switching an expression written for container stats into the log context.

Related errors


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

Appendix: source

Thrown at internal/notification/manager.go:203

				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
					}
				}
			case "metricExpression":
				if exprStr, ok := value.(string); ok {
					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

View on GitHub (pinned to d9463cbe21)