{"record":{"id":"d2545be439380f68","repo":"amir20/dozzle","slug":"failed-to-compile-metric-expression-w-d2545b","errorCode":null,"errorMessage":"failed to compile metric expression: %w","messagePattern":"failed to compile metric expression: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/notification/types.go","lineNumber":191,"sourceCode":"\t\tprogram, err := expr.Compile(s.ContainerExpression, expr.Env(types.NotificationContainer{}))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to compile container expression: %w\", err)\n\t\t}\n\t\ts.ContainerProgram = program\n\t}\n\n\tif s.LogExpression != \"\" {\n\t\tprogram, err := expr.Compile(s.LogExpression, expr.Env(types.NotificationLog{}))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to compile log expression: %w\", err)\n\t\t}\n\t\ts.LogProgram = program\n\t}\n\n\tif s.MetricExpression != \"\" {\n\t\tprogram, err := expr.Compile(s.MetricExpression, expr.Env(types.NotificationStat{}))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to compile metric expression: %w\", err)\n\t\t}\n\t\ts.MetricProgram = program\n\t}\n\n\tif s.EventExpression != \"\" {\n\t\tprogram, err := expr.Compile(s.EventExpression, expr.Env(types.NotificationEvent{}))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to compile event expression: %w\", err)\n\t\t}\n\t\ts.EventProgram = program\n\t}\n\n\treturn nil\n}\n\n// DispatcherConfig represents a dispatcher configuration\ntype DispatcherConfig struct {\n\tID       int               `json:\"id\" yaml:\"id\"`","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/notification/types.go#L173-L209","documentation":"CompileExpressions compiles MetricExpression with expr against types.NotificationStat. A syntactically invalid expression or reference to fields absent from NotificationStat fails compilation and returns this wrapped error; MetricProgram stays nil so the rule never evaluates.","triggerScenarios":"Subscription with non-empty MetricExpression failing expr.Compile(expr, expr.Env(types.NotificationStat{})) during AddSubscription, ReplaceSubscription, loadSubscription, or compiledSub.","commonSituations":"Metric alert rules referencing fields like cpu.percent that don't exist on NotificationStat; comparing a string to a numeric stat; typos after refactoring the stat type.","solutions":["Read the wrapped expr error to find the offending identifier/token","Use only fields defined on types.NotificationStat (numeric comparisons must use numeric fields)","Test-compile the expression with the NotificationStat env before saving","Update types.NotificationStat if a legitimately needed field is missing"],"exampleFix":"// before\ns.MetricExpression = \"stat.cpuPercent > 90\" // unknown field\n// after\ns.MetricExpression = \"stat.CPUPercent > 90\"","handlingStrategy":"validation","validationCode":"func validMetricExpr(s string) error {\n    _, err := expr.Compile(s, expr.Env(types.NotificationStat{}))\n    return err\n}","typeGuard":null,"tryCatchPattern":"if err := sub.CompileExpressions(); err != nil {\n    return fmt.Errorf(\"invalid metric rule: %w\", err)\n}","preventionTips":["Use numeric fields from NotificationStat for thresholds","Compile-test metric rules before saving them","Update expressions after any NotificationStat field rename"],"tags":["notifications","expr-lang","metrics","expression-compilation"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}