SigNoz/signoz · error

could'nt generate nil check for fields referenced in value e

Error message

could'nt generate nil check for fields referenced in value expr of add operator %s: %w

What it means

For enabled add operators whose Value is an EXPRESSION — value of the form EXPR(...) — getOperators extracts the expression and runs fieldsReferencedInExprNotNilCheck to generate nil-guards for every referenced field. If that helper cannot resolve/guard the referenced fields (unknown field syntax, empty expression, parse failure), the builder fails with this wrapped error (note the typo 'could'nt' in the message — match on it exactly if you string-match).

Source

Thrown at pkg/query-service/app/logparsingpipeline/pipelineBuilder.go:137

						"couldn't generate nil check for parseFrom of grok op %s: %w", operator.Name, err,
					)
				}
				operator.If = parseFromNotNilCheck

			} else if operator.Type == "json_parser" {
				operators, err := processJSONParser(&operator)
				if err != nil {
					return nil, fmt.Errorf("couldn't process json_parser op %s: %s", operator.Name, err)
				}

				filteredOp = append(filteredOp, operators...)
				continue // Continue here to skip deduplication of json_parser operator
			} else if operator.Type == "add" {
				if strings.HasPrefix(operator.Value, "EXPR(") && strings.HasSuffix(operator.Value, ")") {
					expression := strings.TrimSuffix(strings.TrimPrefix(operator.Value, "EXPR("), ")")
					fieldsNotNilCheck, err := fieldsReferencedInExprNotNilCheck(expression)
					if err != nil {
						return nil, fmt.Errorf(
							"could'nt generate nil check for fields referenced in value expr of add operator %s: %w",
							operator.Name, err,
						)
					}
					if fieldsNotNilCheck != "" {
						operator.If = fieldsNotNilCheck
					}
				}
			} else if operator.Type == "move" || operator.Type == "copy" {
				fromNotNilCheck, err := fieldNotNilCheck(operator.From)
				if err != nil {
					return nil, fmt.Errorf(
						"couldn't generate nil check for From field of %s op %s: %w", operator.Type, operator.Name, err,
					)
				}
				operator.If = fromNotNilCheck
			} else if operator.Type == "remove" {
				fieldNotNilCheck, err := fieldNotNilCheck(operator.Field)

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Unwrap the error to see why fieldsReferencedInExprNotNilCheck failed.
  2. Simplify the expression: reference only concrete attribute/resource fields (attributes.x, resource.y) that exist upstream.
  3. Confirm the EXPR(...) wrapper is well-formed — non-empty body, balanced parentheses, no stray quotes.
  4. Move complex logic into earlier operators (regex/json parsers) so the add expression only combines already-created fields.

Example fix

// before
- type: add
  enabled: true
  name: total
  value: "EXPR()"  // empty expression

// after
- type: add
  enabled: true
  name: total
  value: "EXPR(attributes.price * attributes.qty)"
Defensive patterns

Strategy: validation

Validate before calling

func validExprValue(v string) bool {
	if !strings.HasPrefix(v, "EXPR(") { return true }
	inner := strings.TrimSuffix(strings.TrimPrefix(v, "EXPR("), ")")
	return strings.TrimSpace(inner) != ""
}
if op.Type == "add" && op.Enabled && !validExprValue(op.Value) {
	return fmt.Errorf("add operator %s has an empty EXPRESSION", op.Name)
}

Type guard

func isAddExprOpValid(op pipelinetypes.PipelineOperator) bool {
	return op.Type != "add" || !op.Enabled || validExprValue(op.Value)
}

Prevention

When it happens

Trigger: An add operator with value like EXPR(attributes.foo + attributes.bar) where the expression references fields the nil-check generator cannot handle, or an empty/malformed EXPR(). Applying the pipeline triggers the failure.

Common situations: Hand-written pipeline YAML with EXPR syntax errors; referencing nested/temporary fields not yet defined at that stage of the pipeline; version differences in the expression mini-language.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/b35fb343ec638b81. Report an issue: GitHub.