SigNoz/signoz · error

could not create nil check for %s: %w

Error message

could not create nil check for %s: %w

What it means

After successfully extracting referenced fields from an expression, the builder calls fieldNotNilCheck on each deepest field path. This error means one of those extracted paths still could not be turned into a nil-check, i.e. the expression referenced a field with an invalid root or malformed path. It is the field-level companion of the expr extraction errors.

Source

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

	// Generating nil check for deepest fields takes care of their prefixes too.
	// Eg: `attributes.test.value + len(attributes.test)` needs a nil check only for `attributes.test.value`
	deepestFieldRefs := []string{}
	for _, field := range referencedFields {
		isPrefixOfAnotherReferencedField := slices.ContainsFunc(
			referencedFields, func(e string) bool {
				return len(e) > len(field) && strings.HasPrefix(e, field)
			},
		)
		if !isPrefixOfAnotherReferencedField {
			deepestFieldRefs = append(deepestFieldRefs, field)
		}
	}

	fieldExprChecks := []string{}
	for _, field := range deepestFieldRefs {
		checkExpr, err := fieldNotNilCheck(field)
		if err != nil {
			return "", fmt.Errorf("could not create nil check for %s: %w", field, err)
		}
		fieldExprChecks = append(fieldExprChecks, fmt.Sprintf("(%s)", checkExpr))
	}

	return strings.Join(fieldExprChecks, " && "), nil
}

// Expr AST visitor for extracting referenced log fields
// See more at https://github.com/expr-lang/expr/blob/master/ast/visitor.go
type logFieldsInExprExtractor struct {
	referencedFields []string
}

func (v *logFieldsInExprExtractor) Visit(node *ast.Node) {
	if n, ok := (*node).(*ast.MemberNode); ok {
		memberRef := n.String()

		// coalesce ops end up as MemberNode right now for some reason.

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Prefix every referenced field with a valid root: attributes.*, resource.*, body
  2. Remove stray/empty path segments (trailing dots, double dots)
  3. Lint all expressions in the pipeline before applying

Example fix

// before
value: "expr:duration_ms / 1000"
// after
value: "expr:attributes.duration_ms / 1000"
Defensive patterns

Strategy: validation

Validate before calling

program, err := expr.Compile(s, expr.Env(map[string]interface{}{}))
if err != nil { return err }
// then walk referenced identifiers and validate roots
for _, id := range collectIdentifiers(program) {
  if !validFieldPath(id) { return fmt.Errorf("invalid field %q in expr", id) }
}

Type guard

func exprFieldsAllValid(s string) bool { return isValidExpr(s) && allFieldsValid(collectIdentifiers(s)) }

Try / catch

Wrap pipeline API errors and highlight the offending field from the message ('could not create nil check for X').

Prevention

When it happens

Trigger: An expression like "foo + attributes.bar" or "resource" where a referenced identifier is not a valid log field root/path; also paths with trailing dots or empty segments inside an otherwise parseable expr.

Common situations: Using bare attribute names in expressions (user_id instead of attributes.user_id); referencing metadata keys that don't exist under resource.; copying expressions from other tools (Grafana/OTTL) with different root conventions.

Related errors


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