Dry-run rejected my OTTL expression
You wrote an OTTL statement in a Transform or Filter step, ran the dry-run, and the step came back with an error instead of a result.
This is the preview working as intended. The statement is parsed by the same OTTL engine the collector runs, so an expression rejected here would have been rejected on the host — with the difference that here it costs you nothing.
Read the error by its shape
Section titled “Read the error by its shape”Every message starts with validate config: and then takes one of a small
number of forms.
statement has invalid syntax: 1:6: unexpected token "="
Section titled “statement has invalid syntax: 1:6: unexpected token "="”The statement does not parse. The two numbers are line:column, so
1:6 points at character 6 — start reading there.
The most common cause by far is writing an assignment where OTTL wants a function call:
body = "redacted" # wrong — OTTL has no assignment operator
set(body, "redacted") # right
A truncated where clause produces the same shape, with the column at the
end of the statement:
set(body, "x") where attributes["k"] == # unexpected token "<EOF>"
lexer: invalid input text "\"oops)"
Section titled “lexer: invalid input text "\"oops)"”An unterminated string literal — a quote you opened and never closed. The quoted fragment in the message is the text the lexer choked on, which is everything from the opening quote onward.
undefined function "redact"
Section titled “undefined function "redact"”The function does not exist in OTTL. Check the spelling, and check that you are not reaching for a function from a different tool. The functions you are most likely to want:
| To do this | Use |
|---|---|
| Set a field to a value | set(field, value) |
| Replace regex matches inside a string | replace_pattern(field, pattern, replacement) |
| Replace a whole matching value | replace_match(field, pattern, replacement) |
| Remove attribute keys | delete_key(attributes, "key") |
| Keep only some attribute keys | keep_keys(attributes, ["a", "b"]) |
To redact PII, prefer the PII Masking processor over hand-written statements — it carries maintained detectors and can be previewed the same way. See Mask PII.
segment "span" from path "log.span.name" is not a valid path
Section titled “segment "span" from path "log.span.name" is not a valid path”The field does not exist in the context you chose. The message ends
with the context it checked — the log context above.
Note that the path in the message is log.span.name even though you
wrote span.name: the context you selected is prefixed to every path in
the statement. That prefix is why an expression copied from a trace
pipeline fails in a log one — span.name is a real path in the span
context and nothing at all in the log context.
Fix it by choosing the right context for the step, or the right field for
the context you are in. In the log context the fields you will use most
are body, severity_text, severity_number, attributes[...],
resource.attributes[...], and time_unix_nano.
incorrect number of arguments. Expected: 2 Received: 1
Section titled “incorrect number of arguments. Expected: 2 Received: 1”The function exists but you gave it the wrong number of arguments —
set(body) where set needs a field and a value. The counts in the
message are exact; no argument is optional here.
the regex pattern supplied to replace_pattern '"([a-z"' is not a valid pattern
Section titled “the regex pattern supplied to replace_pattern '"([a-z"' is not a valid pattern”The statement parsed, but the regular expression inside it did not
compile. The trailing part of the message is the regex engine’s own error
(missing closing ], missing closing ), and so on) and names the defect
precisely.
Two things to watch for:
- Escaping. A backslash usually has to survive both the config format
and the regex, so a literal dot is often
\\.rather than\.. - The dialect. Collectors use RE2, which has no backreferences and no lookaround. A pattern copied from Perl, Python, or JavaScript may be valid there and rejected here.
When the statement is valid but the result is wrong
Section titled “When the statement is valid but the result is wrong”If there is no error and the output still isn’t what you wanted:
- Nothing changed. The statement ran and matched nothing. Check the
sample really contains what you think — a
whereclause that never holds produces exactly this, silently. - Everything vanished. A Filter step drops records where its
expression is
true, so an inverted condition drops the whole batch and the panel marks the chain as ending in a drop. Note that a route input filter has the opposite sense — it keeps what matches. An expression moved from one to the other has to be negated. - The step says “Unsupported”. The step is not a dry-run failure at all — that processor type has no preview implementation yet, and the record passes through untouched. It will still run on the collector.
- A masking rule with a salted hash refuses to preview. That is deliberate: the salt is resolved only at delivery, so any digest shown here would be computed with the wrong salt. Test the same rule in full redaction mode to confirm what it finds, then switch back.
Related
Section titled “Related”- Preview a processor chain — the preview workspace in depth
- Build your first pipeline — chain editor walkthrough
- Filter records on a route — filter conditions and their cookbook
- Capture live samples — preview against real telemetry
- Config not applying after save — when a verified chain doesn’t reach the collector