---
title: "Expression & Value-Mapping Errors"
description: "Diagnose expression evaluation and value-mapping failures on a tag"
source_url: https://ai-ops.com/docs/troubleshoot/expressions-and-mapping
---

# Expression & Value-Mapping Errors

This is the **transformation layer** of tag troubleshooting. The device connection is up and a raw value is arriving, but the step that turns that raw value into the tag's final value is failing. Two error codes live here:

| Code | Label | What's failing |
|------|-------|----------------|
| **110** | Bad: Expression | The tag's calculated expression failed to evaluate |
| **108** | Mapping Error | Value mapping could not turn the raw value into an output |

There is also an unflagged problem that surfaces only as a warning icon on the tag overview: **multiple sources writing to the same output tag**. It's covered at the end of this page.

Before you dig in, confirm the layers below this one are healthy. If the tag also shows a bad-quality read code (100-107) or its parent device has failed (code 1), fix that first. See [Bad, Missing, or Frozen Tag Values](https://ai-ops.com/docs/troubleshoot/tag-values.md) and [Troubleshoot a Connection](https://ai-ops.com/docs/troubleshoot/connection.md). For the shared model of the three diagnostic fields (error code, error message, error detail), the status and quality legend, and the auto-clear behavior, see [Reading Status, Quality & Errors](https://ai-ops.com/docs/troubleshoot/reading-status-and-errors.md).

> [!NOTE] Where to read the error
> On the tag's **Overview** tab the red error strip shows the message and detail — click it to copy both. All three fields are also in the **Parameters** tab under **Live Data**. For expression tags, the **Expression** card on the Overview tab shows the formula and its most recent computed result, if any.

## Expression Error (code 110)

A tag with **Source: Expression** computes its value from a formula run by the Expression Evaluator. When that formula can't produce a number, the tag goes to a **Failed** state with error code **110**. The error detail usually names the offending part of the expression. Work through the causes below in order.

### 1. Syntax errors and typos

A malformed formula never evaluates. Common shapes: unbalanced parentheses, a stray operator, a misspelled function name (`avg(...)` instead of `mean(...)`), or a reference typed by hand that doesn't match a real tag name.

Open the tag's **Configuration** tab and re-check the expression. Rebuild any reference using the `@` autocomplete menu rather than typing it — this guarantees the name and field are spelled correctly and registers a tracked dependency so the expression re-evaluates when that source changes.

> [!TIP] Always insert references with @
> Type `@` in the expression editor to search tags, devices, models, and bindings, then pick the field. A hand-typed reference that is one character off will read as a missing tag and fail with code 110. See [Expression Tags](https://ai-ops.com/docs/tags/expressions.md) for the full reference and function catalog.

### 2. Division by zero

`a / b` fails the instant `b` evaluates to `0`. This is intermittent by nature — the expression works until a referenced tag momentarily reads zero. Guard the denominator with a conditional:

```text
@[Flow:value] / @[Area:value] if @[Area:value] != 0 else 0
```

The same applies to `log(x)` at or below zero and to `pow()` with an invalid base/exponent pair.

### 3. Missing or failed referenced tags

If the expression references a tag, device, model, or binding that has been deleted, disabled, or renamed, the reference can no longer resolve. A referenced source that is itself in a **Failed** state can also propagate a bad value into the calculation.

- Confirm every referenced entity still exists and is enabled.
- Reference the source's **status** or **error_code** field to build fallback logic instead of failing outright. For example, switch to a backup when the primary isn't running:

```text
@[Primary:value] if @[Primary:status] == 1 else @[Backup:value]
```

### 4. Circular dependencies

Expression A references expression B, and B references A (directly or through a chain). Neither can produce a value, so both fail with code 110. Trace the `@` references on each tag in the loop and break the cycle — usually by pointing one expression at the underlying source tag rather than at another expression.

### 5. Disallowed fields

Only specific fields are exposed on each reference type: tags expose `value`, `status`, and `error_code`; devices, models, and bindings expose `status` and `error_code` (bindings also expose `value`). Referencing a field that a given type doesn't provide fails to evaluate. Use the `@` menu — it only lists the fields that are valid for the entity you picked. The full field list per reference type is in [Expression Tags](https://ai-ops.com/docs/tags/expressions.md).

### Isolating an expression failure

1. Read the **error detail** on the Overview error strip — it typically points at the specific token or operation that failed.
2. Simplify the formula down to a single reference (`@[Source:value]`), save, and confirm it computes. Add complexity back one piece at a time.
3. Set the Expression Evaluator service to **Debug** log level to see each evaluation. See [Logs](https://ai-ops.com/docs/system/logs.md).

Once the formula is corrected, the next successful evaluation clears the error automatically — no manual acknowledgement is needed.

## Value-Mapping Error (code 108)

Value mapping runs an ordered list of match rules against each raw value the tag receives; the first matching rule sets the output. Error code **108** means the mapping step failed for this tag. The overwhelmingly common cause is a value that **matched no rule**.

Value mapping rules are evaluated top-to-bottom. If the incoming value doesn't satisfy any rule — an unexpected status string, a number outside every configured band — the tag enters an error state.

### The fix: add a catch-all "Any" rule

Add a rule with match type **Any (Catch-all)** as the **last** rule in the list. "Any" always matches, so it guarantees every value produces an output instead of erroring. Give it a sentinel output (for example `-1`) so unexpected values are visibly distinct from real ones.

| # | Match Type | Pattern | Output |
|---|------------|---------|--------|
| 1 | Exact | Off | 0 |
| 2 | Exact | On | 1 |
| 3 | Any | — | -1 |

With rule 3 in place, a value like `"Standby"` that matches neither `Off` nor `On` falls through to the catch-all and maps to `-1` rather than failing.

> [!WARNING] No catch-all means unmatched values fail
> If value mapping is enabled but no rule matches the incoming value, the tag goes to error code 108. Always end the rule list with an **Any** rule unless you deliberately want unmatched values to error.

Other things to check when code 108 persists even with a catch-all:

- **Numeric rules against non-numeric input.** Greater Than, Less Than, Between, etc. are skipped when the raw value can't be parsed as a number, so a purely numeric rule set with no Exact or Any fallback will miss text values.
- **Case sensitivity.** If the device sends `"OFF"` but your Exact rule is `Off`, enable **Case-Insensitive Matching** or add the exact variant.
- **Reverse mapping on output tags.** Reverse mapping (numeric output back to a string on write) only works with **Exact Match** rules. If the value being written has no matching Exact rule, the write side has nothing to convert.

For rule types, ordering, the lookup key, and reverse mapping mechanics, see [Value Mapping](https://ai-ops.com/docs/tags/value-mapping.md).

> [!TIP] Use the lookup key to see what arrived
> When mapping is active, the tag's live data shows both the numeric **Value** and the **Lookup Key** (the original raw value, in brackets). If the tag is erroring, the lookup key tells you exactly which raw value none of your rules caught.

## "Multiple sources are writing to this tag"

This is a conflict, not an error code — the tag keeps running, but its output may behave unpredictably. It applies only to **output** tags.

An output tag is meant to have a single writer. Koios can write to an output tag from three kinds of source:

| Source | Meaning |
|--------|---------|
| **AI Model** | A model binding writes its prediction to the tag |
| **Mapping** | A value mapping produces the tag's output |
| **Component** | A component (connector) writes the tag |

When more than one of these targets the same output tag, the **Output Source** metric card on the tag's Overview tab turns red with a warning triangle and a tooltip warning that multiple sources are writing to the tag. The last writer in a given cycle wins, so the value you see can flip depending on timing.

### How to resolve it

1. On the output tag's **Overview** tab, read the **Output Source** card — it lists every source currently writing the tag.
2. Decide which single source should own the output.
3. Remove the others: delete or repoint the extra model binding, remove the value mapping, or reconfigure the component so it no longer targets this tag.
4. Confirm the Output Source card shows exactly one source and the warning triangle is gone.

> [!NOTE] One writer per output tag
> A healthy output tag reports a single Output Source. If you intend a model to drive the tag, it should not also carry a value mapping — and vice versa.

## What's Next

- [Reading Status, Quality & Errors](https://ai-ops.com/docs/troubleshoot/reading-status-and-errors.md) — the shared three-field diagnostic model, status/quality legend, and stuck-error checklist
- [Bad, Missing, or Frozen Tag Values](https://ai-ops.com/docs/troubleshoot/tag-values.md) — fix bad-quality reads before the transformation layer
- [A Model or Binding Isn't Running](https://ai-ops.com/docs/troubleshoot/models.md) — when the AI Model source of an output tag is failing upstream
- [Troubleshooting Koios](https://ai-ops.com/docs/troubleshoot/introduction.md) — the full symptom router
- [Expression Tags](https://ai-ops.com/docs/tags/expressions.md) — authoring reference: operators, functions, and the `@` reference syntax
- [Value Mapping](https://ai-ops.com/docs/tags/value-mapping.md) — match-rule types, ordering, lookup key, and reverse mapping
- [Logs](https://ai-ops.com/docs/system/logs.md) — set the Expression Evaluator to Debug and stream its output
