VRL error reference
VRL is a fail-safe language, which means that a VRL program doesn’t compile unless every potential error is handled. Observability data is notoriously unpredictable and fail safety ensures that your VRL programs elegantly handle malformed data.
Compile-time errors
100 Unhandled root runtime error
Rationale
Resolution
Examples
Unhandled root runtime error (assigning)
get_env_var("HOST")
- get_env_var("HOST")
+# .host = get_env_var("HOST")
101 Malformed regex literal
Rationale
Resolution
parse_*
functions. If
you don’t see a function for your format please request it. Otherwise, use the
Rust regex tester to test and correct your regular expression.Examples
Malformed regex literal (common format)
. |= parse_regex!(.message, r'^(?P<host>[\w\.]+) - (?P<user>[\w]+) (?P<bytes_in>[\d]+) \[?P<timestamp>.*)\] "(?P<method>[\w]+) (?P<path>.*)" (?P<status>[\d]+) (?P<bytes_out>[\d]+)$')
-. |= parse_regex!(.message, r'^(?P<host>[\w\.]+) - (?P<user>[\w]+) (?P<bytes_in>[\d]+) \[?P<timestamp>.*)\] "(?P<method>[\w]+) (?P<path>.*)" (?P<status>[\d]+) (?P<bytes_out>[\d]+)$')
+. |= parse_common_log!(.message)
102 Non-boolean if expression predicate
Rationale
1
) since these
are common foot-guns that can result in unexpected behavior when used in if expressions. This provides important
safety guarantees in VRL and ensures that VRL programs are reliable once deployed.Resolution
exists
and
is_nullish
.Examples
Non-boolean if expression predicate (strings)
{
"message": "key=value"
}
if .message {
. |= parse_key_value!(.message)
}
-if .message {
+if exists(.message) {
. |= parse_key_value!(.message)
}
103 Unhandled fallible assignment
Rationale
Resolution
Examples
Unhandled fallible assignment (coalescing)
{
"message": "key=value"
}
. = parse_key_value(.message)
-. = parse_key_value(.message)
+. = parse_key_value(.message) ?? {}
Unhandled fallible assignment (raising)
{
"message": "key=value"
}
. = parse_key_value(.message)
-. = parse_key_value(.message)
+. = parse_key_value!(.message)
Unhandled fallible assignment (assigning)
{
"message": "key=value"
}
. = parse_key_value(.message)
-. = parse_key_value(.message)
+., err = parse_key_value(.message)
104 Unnecessary error assignment
Rationale
Resolution
Examples
Unnecessary error assignment (strings)
.message, err = downcase(.message)
-.message, err = downcase(.message)
+.message = downcase(.message)
105 Undefined function
Resolution
Examples
Undefined function (typo)
parse_keyvalue(.message)
-parse_keyvalue(.message)
+parse_key_value(.message)
106 Function argument arity mismatch
Resolution
Examples
Function argument arity mismatch
parse_json(.message, pretty: true)
-parse_json(.message, pretty: true)
+parse_json(.message)
107 Required function argument missing
Resolution
Examples
Required function argument missing
parse_timestamp(.timestamp)
-parse_timestamp(.timestamp)
+parse_timestamp(.timestamp, format: "%D")
108 Unknown function argument keyword
Resolution
Examples
Unknown function argument keyword
parse_timestamp(.timestamp, fmt: "%D")
-parse_timestamp(.timestamp)
+parse_timestamp(.timestamp, format: "%D")
110 Invalid argument type
Rationale
Resolution
Examples
Invalid argument type (guard with defaults)
downcase(.message)
+.message = string(.message) ?? ""
downcase(.message)
Invalid argument type (guard with errors)
downcase(.message)
downcase(string!(.message))
111 Unhandled predicate error
Rationale
Resolution
Examples
Unhandled predicate error (predicate)
if contains(.field, "thing") {
log("thing")
}
- if contains(.field, "thing") {
+# if contains(.field, "thing") ?? false {
203 Unrecognized token
Resolution
Examples
Unrecognized token
😂
-😂
+"some valid value"
204 Unrecognized end-of-file (EOF)
Resolution
Examples
Unrecognized end-of-file (EOF)
.field1 = "value1"
.field2 =
-.bar =
+.field2 = "value2"
205 Reserved keyword
Resolution
Examples
Reserved keyword
else = "some value"
-else = "some value"
+some_non_reserved_name = "some value"
206 Invalid numeric literal
207 Invalid string literal
Resolution
Examples
Invalid string literal
"Houston, we have a problem'
- "Houston, we have a problem'
+ "Houston, we have a problem"
208 Invalid literal
209 Invalid escape character
300 Unexpected type
301 Type coercion error
302 Remainder error
303 Multiplication error
304 Division error
305 Divide by zero
Rationale
Resolution
If you know that a value is necessarily zero, don’t divide by it. If a value could be zero, capture the potential error thrown by the operation:
result, err = 27 / .some_value
if err != null {
# Handle error
}
306 NaN float
307 Addition error
308 Subtraction error
309 Or expression error
310 And expression error
311 Greater than error
312 Greater than or equal to error
313 Less than error
314 Less than or equal to error
315 mutation of read-only value
400 Unexpected expression
401 Invalid enum variant
Resolution
402 Expected static expression for function argument
VRL expected a static expression for a function argument, but a dynamic one was provided (such as a variable).
VRL requires static expressions for some function arguments to validate argument types at compile time to avoid runtime errors.
Resolution
403 Invalid argument
Resolution
601 Invalid timestamp
t'...'
syntax) but the timestamp doesn’t adhere to RFC 3339 format.Rationale
Resolution
Examples
Invalid timestamp formatting
.timestamp = format_timestamp!(t'next Tuesday', format: "%v %R")
-.timestamp = format_timestamp!(t'next Tuesday', format: "%v %R")
+.timestamp = format_timestamp!(t'2021-03-09T16:33:02.405806Z', format: "%v %R")
620 Aborting infallible function
Rationale
!
in the function call.Resolution
!
from the function call.Examples
Aborting infallible function
encode_json!(["one", "two", "three"])
- encode_json!(["one", "two", "three"])
+# encode_json(["one", "two", "three"])
630 Fallible argument
Rationale
Resolution
!
, coalescing
the error using ??
, or via some other method.Examples
Fallible argument
format_timestamp!(to_timestamp("2021-01-17T23:27:31.891948Z"), format: "%v %R")
- format_timestamp!(to_timestamp("2021-01-17T23:27:31.891948Z"), format: "%v %R")
+ format_timestamp!(to_timestamp!("2021-01-17T23:27:31.891948Z"), format: "%v %R")
631 Fallible abort message expression
Rationale
Resolution
??
, or via some other method.Examples
Fallible abort message expression
abort to_syslog_level(0)
- abort to_syslog_level(0)
+ abort to_syslog_level(0) ?? "other"
640 No-op assignment
Rationale
_
), this operation is considered a “no-op” as it has no effect (and is thus not an assignment at
all).Resolution
Examples
No-op assignment
_ = "the hills are alive"
- _ = "the hills are alive"
+# .movie_song_quote = "the hills are alive"
650 Chained comparison operators
Rationale
1 != 2
. Chaining them together, as in
1 < 2 < 3
, produces a meaningless non-expression.Resolution
a == b == c
, for example, isn’t valid,
a == b && b == c
is valid because it involves distinct Boolean expressions.Examples
Chained comparison operators
1 == 1 == 2
- 1 == 1 == 2
+# (1 == 1) && (1 == 2)
651 Unnecessary error coalescing operation
??
) to handle an error, but in this case the left-hand
operation is infallible, and so the right-hand value after ??
is never reached.Rationale
Error coalescing operations are useful when you want to specify what happens if an operation fails. Here’s an example:
result = op1 ?? op2
In this example, if op1
is infallible (that is, it can’t error) then the result
variable
if set to the value of op1
while op2
is never reached.
Resolution
??
operator and the
right-hand operation. If, however, the left-hand operation is supposed to be fallible,
remove the !
from the function call and anything else that’s making it infallible.652 Only objects can be merged
Rationale
Amongst VRL’s available types, only objects can be merged together. It’s not clear what it would mean to merge, for example, an object with a Boolean. Please note, however, that some other VRL types do have merge-like operations available:
- Strings can be concatenated together
- Arrays can be appended to other arrays
These operations may come in handy if you’ve used merge
by
accident.
Resolution
object
function to
check.660 Non-Boolean negation
Rationale
!
). The expression !false
, for example, produces
true
, whereas !"hello"
is a meaningless non-expression.Resolution
Examples
Non-Boolean negation
!47
- !47
+# !(47 == 48)
701 Call to Undefined Variable
Rationale
Resolution
Examples
Undefined variable
my_variable
+my_variable = true
my_variable
Wrong variable name
my_variable = true
my_var
-my_var
+my_variable
801 Usage of deprecated item
Rationale
Resolution
Runtime errors
A runtime error occurs after compilation and during program runtime. Because VRL is fail safe, all runtime errors must be handled. This forces you to address how VRL programs should respond to errors.
Runtime errors are strings that describe the error.
Handling
You have three options for handling errors in VRL:
Assigning
As documented in the assignment expression reference, you can assign errors when invoking an expression that’s fallible. When assigned, runtime errors are simple strings:
structured, err = parse_json("not json")
if err != null {
log("Unable to parse JSON: " + err, level: "error")
} else {
. = merge(., structured)
}
If the expression fails, the ok
assignment target is assigned the “empty” value of its type:
# `.foo` can be `100` or `"not an int"`
foo, err = to_int(.foo)
# `err` can be `null` or `"unable to coerce value to integer"`
if err == null {
# `foo` can be `100` or `0`
.result = foo * 5
}
The above example compiles because foo
will either be assigned the integer representation of
.foo
if it can be coerced to an integer, or it will be set to the “empty integer value” 0
if
.foo
can’t be coerced into an integer.
Because of this, it is important to always check whether err
is null before using the ok
value
of an infallible assignment.
Empty values
Type | Empty value |
---|---|
String | "" |
Integer | 0 |
Float | 0.0 |
Boolean | false |
Object | {} |
Array | [] |
Timestamp | t'1970-01-01T00:00:00Z' (Unix epoch) |
Regular expression | r'' |
Null | null |
Coalescing
As documented in the coalesce expression reference, you can coalesce errors to efficiently step through multiple expressions:
structured = parse_json("not json") ?? parse_syslog("not syslog") ?? {}
. = merge(., structured)
Raising
As documented in the function call reference, you can raise errors to immediately abort
the program by adding a !
to the end of the function name:
structured = parse_json!("not json")
. = merge(., structured)