Skip to contents

This vignette outlines errors that might be generated when parsing odin code, with more explanation about the error and how they can be avoided. Don’t read this top to bottom as it’s quite boring! However, if we get errors that benefit from more explanation about why they’ve been thrown then we’ll expand on the contents here and arrange for these to be linked from the thrown error directly.

The error numbers are arbitrary after the first digit. The first digit will correspond to different phases of the parsing:

  • E0xxx - general errors
  • E1xxx - errors during parsing of individual expressions
  • E2xxx - errors when considering the system as a whole

When an error is thrown you will be directed here, for example:

odin2::odin({
  initial(x) <- 1
  update(x) <- 1
  1 < 10
})
#> Error in `odin2::odin()`:
#> ! Unclassifiable expression
#>  Expected an assignment (with '<-') or a relationship (with '~')
#> → Context:
#> 1 < 10
#>  For more information, run `odin2::odin_error_explain("E1001")`

You can then print the explanation:

odin2::odin_error_explain("E1001")
#> 
#> ── E1001 ───────────────────────────────────────────────────────────────────────
#> We were not able to classify an expression in your odin source code.
#> 
#> Example:
#> 
#>     a + 1
#> 

E0001

You have used a feature that is not yet implemented, but which is intended to be implemented. Try again later. Probably the code you have written works well in odin v1.x.x but has not been implemented in odin2.

In some cases, code that produces this error may in future produce a different error code, if implementation is forecast to take a while.

E1001

We were not able to classify an expression in your odin source code.

Example:

a + 1

E1002

Invalid assignment of data(). If you use data() on the right hand side of an expression, then the left hand side must be a symbol.

Example:

initial(x) <- data()

E1003

Invalid input to a special lhs function (initial(), update(), etc). These functions all (currently) accept a single unnamed argument.

Examples:

initial() <- 1
initial(a, b) <- 1
initial(x = a) <- 1

E1005

Invalid target on lhs of assignment.

Examples:

1 <- 10

The code above is valid R (as in, it can be parsed) but it is nonsensical. At present the lhs of an assignment must be a symbol (e.g., a <- 1). In future versions we will support assignments into arrays (e.g., a[] <- 1) but this is not yet implemented.

This code is also reported if you have a spelling mistake, such as

inital() <- 1

instead of initial(). It is also reported with this code, which contains two legacy errors.


compare(d) <- Normal(0, 1)

Firstly, there is an error you may have made in the previous version, in which the assignment <- should be the comparison symbol ~. Furthermore, in this version, the compare() function is not required at all, and you should write d ~ Normal(0, 1).

E1006

Invalid call to the parameter() function, used on the rhs of an assignment. If this error is thrown then we have failed to parse the arguments of your call to parameter. The full prototype of parameter() is:

parameter(default = NULL, constant = NULL, differentiate = FALSE)

We will fail to parse your call if:

  • You provide more than three arguments
  • You provide named arguments that do not match the three above (default, constant or differentiate)

Example:

x <- parameter(value = 10)

This fails because value is not a valid keyword argument to parameter.

E1007

Invalid default argument to parameter().

Currently we support very little of odin’s syntax within the default argument definition, though in future we may support more. It’s complicated (and a bit confusing) to allow use of other variables here because we end up with another copy of the dependency graph to consider (we have to be able to resolve all the possible relationships between quantities used as defaults before any of these quantities are used). It’s not impossible to support this and in future we may consider doing so.

At present, you may perform arithmetic operations on literal numbers. This allows you to write:

a <- parameter(1 / 3)

defining a to be a parameter with a default value of 0.33333... without having to write out a long floating point number.

E1008

Invalid differentiate argument to parameter(). You have provided something other than a literal TRUE or FALSE here (e.g., a missing value, an expression or a symbol).

E1009

Invalid constant argument to parameter(). You have provided something other than a literal NULL, TRUE or FALSE here (e.g., a missing value, an expression or a symbol).

E1010

Invalid call to data() used on the right hand side. Currently this function takes no arguments, though later we will expand this to allow description of the data that you wish to use.

Example

d <- data(integer = TRUE)

Here, you have somewhat hopefully requested that d will be data as an integer but we don’t yet support that. Probably this will be supported in future, but the interface is not yet decided. For now all data elements are assumed to be scalar reals.

E1012

Invalid argument on the lhs of a ~ comparison.

Example

x / 2 ~ Normal(0, 1)
1 ~ Normal(0, 1)

The lhs of a ~ comparison must be a symbol. We may expand this in the future to support arrays too.

E1013

Failed to parse the rhs of ~ as a valid distribution. This can fail for many reasons, and the details of the failure come from monty::monty_dsl_parse_distribution

Example reasons for failure include the the rhs being:

  • not a call (e.g., x ~ 1
  • not a call to distribution function (e.g., x ~ sqrt(2))
  • an invalid call (e.g., x ~ Normal(0, 1, 2))

The details for the failure will be included in the body of the error message.

E1014

Invalid assignment of parameter(). If you use parameter() on the right hand side of an expression, then the left hand side must be a symbol.

Example:

initial(x) <- parameter()

E1015

Differentiable parameters must not be constant. You have written

a <- parameter(constant = TRUE, differentiate = TRUE)

which is impossible. Parameters that are differentiable need to be able to be set by dust::dust_system_update_pars() as well as on model creation.

Probably you want to set at least one of these to FALSE, or omit the argument and accept the default.

E1016

Failed to translate a user() expression (valid in odin before version 2) into a call to parameter(). This was likely code that would not work in old odin either.

E1017

Compatibility issues were present in the system (e.g., using user() instead of parameter() and the compatibility action was "error". You can, in the short term, disable failure here by using compatibility = "warning" or compatibility = "silent", but eventually this will become an error that is always thrown when running with old odin code.

The error message will explain how to update your code to use new odin2 syntax.

E1018

Failed to parse a call to a stochastic function (e.g., Normal()). These errors come from monty::monty_dsl_parse_distribution, typically where the function call does not match arguments for any candidate call (some distributions have multiple candidates, distinguished by argument names).

Example calls that will fail:

* `Normal(1, 2, 3)` -- too many arguments
* `Normal()` -- too few arguments
* `Normal(mu = 0, sd = 1)` -- invalid argument names

The details for the failure will be included in the body of the error message.

E1019

Invalid value for the zero_every argument to initial(). At present, this must be a literal value, and that value must be an integer-like number (e.g., 2 or 2L). We may relax this in future to allow more flexibility (e.g., a variable which contains an integer-like number).

Examples that would error

initial(x, zero_every = a) <- 0
initial(y, zero_every = 2.5) <- 0

E1020

The right hand side of a call to initial() that uses the zero_every argument was not 0, but it must be. Because we periodically reset values to zero, any initial condition other than zero makes no sense. See the dust2 docs on periodic variables for details.

Examples that would error

initial(x, zero_every = 1) <- 10
initial(x, zero_every = 1) <- a

E1021

Invalid use of a special array access variable (e.g., i, j, k) on the right hand side of an expression. The available index variables are determined by the rank (number of dimensions) of the variable on the left hand side. If you have a vector you can only use i on the right hand side, if you have a matrix you can use i and j and so on.

Example causing an error:

x[, ] <- a[i, k] + a[i, j]

Above, we have used k on the rhs, but x is only a matrix so this would not work. Think of the above statement as it might appear in generated pseudo-code:

for i in 1:nrow(x):
  for j in 1:ncol(x):
     x[i, j] <- a[i, k] + a[i, j]

and the reason that this is an error should be apparent.

E1022

Invalid use of : within the left hand side of an array assignment. We might increase the number of ways you can use this but for now we are quite strict (the same rules as with version 1 of odin). If you use : it must be the outermost operator within an index, so this is fine:

x[a:b]

but this is not

x[a:b + 1]

This is because we can’t generally convert the latter type into a from:to form, which we need for the code generation to work, and also because R’s parsing rules are fairly ambiguous about if this really means (a:b) + 1 or a:(b + 1)`.

E1023

Invalid functions used within an array index. At the moment you can only use : (the range operator, which must be the outermost function call), +, - and (. The error will indicate the function that you have tried to use, and if you feel this is unreasonable please let us know. We may expand the list of supported functions within arrays in future, with candidates being *, %/% and %%.

E1024

Unary minus (- as “negative” rather than “minus”) detected within arrays. This error is a special case of E1023 but deserves special mention here because it has special meaning in R’s array access. In R, we can write

x[-1]

and this means “all of x except the first element”, which is something we might support in future.

E1025

Invalid use of i, j, etc on the left hand side of an expression, for example:

x[i] <- 2 * a[i]

Usually, this error can be fixed by omitting the i from the left hand side as you probably meant

x[] <- 2 * a[i]

E1026

Something unexpected was used as an array index on the left hand side of an array expression, such as:

x[TRUE] <- 1

E1027

You have tried to use a function that odin does not support.

Example:

a <- pgamma(0, 1)

It’s also possible that you have simply misspelt the function you intended:

a <- sqt(2)

Not all of R’s mathematical functions are supported, but please let us know if you need something that we don’t support.

E1028

Invalid call to an odin function. Usually, this means that you have provided too many or too few arguments, or that you have provided a named argument that the function does not support. The message should guide you to fix the mistake, but the machinery for doing this (currently) comes from match.call which can be unhelpful at times.

Example:

a <- round(b, 2)

We don’t yet support round’s digit argument, so this call will fail.

E1029

Disallowed use of named arguments. For some primitive R functions (e.g., + we disallow use of named argument forms). You are unlikely to see this error, but we would be interested to know if you do.

E1030

Incorrect number of arguments to a function that does not accept argument names. You are unlikely to see this error, but we would be interested to know if you do.

E1031

Invalid type argument to parameter(). You have provided something other than a literal "real", "integer" or "logical" (e.g., a missing value, an expression, symbol, or other string).

E1032

Impossible attempt to differentiate parameter with non-real type. You cannot differentiate integer or logical parameters. Example:

a <- parameter(type = "integer", differentiate = TRUE)

Here, you must decide if a should be differentiable (in which case remove the type argument) or an integer (in which case remove the differentiate argument).

E1033

The argument to sum must be an array. This can either be a complete array (in which case the argument will be a symbol), or an indexed array. So these are both fine:

a <- sum(x)
b[] <- sum(x[, i])

with the first summing over the whole array and the second summing over rows (each element of b will contain a sum over the corresponding row of x.

But these are errors:

a <- sum(a + y)
b[] <- sum([, i] + 1)

Because summation is associative (or commutative) in this case we could write:

a <- sum(a) + sum(y)
b[] <- sum([, i]) + 1

but in more complicated cases you may have to jump through more hoops to get the expression you want, and this may involve saving out an intermediate variable. For example, rather than writing:

a <- sum(x^2)

You might write:

xx[] <- x[i]^2
a <- sum(xx)

E1034

Invalid use of : within a partial sum. If you use : it must be the outermost operator within an index, so this is fine:

sum(x[a:b])

but this is not

sum(x[a:b + 1])

See E1022 for more information in the case where this same class of error is applied to indexing the left hand side of an assignment.

E2001

Your system of equations does not include any expressions with initial() on the lhs. This is what we derive the set of variables from, so at least one must be present.

E2002

No call to deriv() or update() on the lhs of any equation. Every call to initial() requires a call to deriv() or update(), and when there is not even a single call to either of these we can’t tell what sort of time your model runs in (i.e., if it works in continuous or discrete time). This error is related to E2004, but separate because we can’t describe what is missing properly.

E2003

Variables are missing initial conditions.

All variables used in deriv() or update() require a corresponding entry in initial() to set their initial conditions. The error will highlight all lines that have a deriv() or update() call that lacks a call to initial(). This can sometimes be because you have a spelling error in your call to initial().

E2004

Variables are missing calls to deriv() or update()

You have a system where you use different equations for deriv()/update() to the variables defined in initial(). This is an error if there are equations in deriv()/update() that don’t have a corresponding equation using initial(), or if you have equations in initial() that don’t have a corresponding deriv() or update() equation. The error will highlight all lines that might be involved in the error.

E2005

Cyclic dependency detected within equations. There are a few ways this can happen. The simplest is that your equation references itself, for example:

a <- a + 1

Unlike in R, this is disallowed, as each variable may only be assigned to once within the target function of your system. Each assignment is much more like mathematical equation than usual programming statements.

You can get more complicated cycles, for example:

a <- c / 2
b <- sqrt(a)
c <- a + 1

Here a depends on c, c depends on b and b depends on a. The error will reference all the variables involved in cycle.

It is possible that there is more than one cycle within the reported expressions.

E2006

Undefined variable used in an equation. This error means that you have referenced some variable that does not exist within the odin system. Common reasons for this error include:

  • A spelling mistake: you’ve referenced a variable that is very similar to the one that you meant to (we may add “did you mean support” in future; let us know if this would have saved you time).
  • Trying to reference variables defined in R’s environment but not in odin. This is impossible, but you might want to make a parameter, perhaps.

Example:

initial(a) <- 1
update(a) <- a * r
r <- exp(v)

This will error because v (referenced by r, which is referenced by update(a)) is undefined.

E2007

Trying to use dt in a continuous time (ODE) system. This is really a special case of E2006, but we treat it separately because it usually means that something has gone badly with the system design.

E2008

An expression assigning as an array did not have a corresponding call to dim(). We always need this, even if it looks like we should be able to work out how long your array is. You probably just need to add a call like

dim(x) <- ...

for the variables mentioned in the error, with the appropriate lengths.

E2009

You have tried to assign to an array variable (i.e., something with a dim() call) without using [] on the left hand side.

Example:

dim(a) <- 5
a <- 0

If you wanted a length-5 array of zeros here, you should write

a[] <- 0

E2010

Can’t reference data outside of equations that compare to data. You have tried to reference some data (a variable that exists on the lhs of a call to data()) from an equation that is used anywhere other than a comparison expression (involving ~, or a dependency of these equations). You cannot do this, because data do not exist at this point.

Here’s a trivial example that would error:

initial(x) <- 1
update(x) <- x + d
d <- data()

Here, d defines some data, and we try to use it from update() but we just can’t do that.