Diagnostics & Error Codes
Strategy Lab diagnostics are the messages the engine shows when it cannot safely run your YAML, or when it can run but wants you to notice something about the way a rule behaved.
Written By Axiom Admin
Last updated 2 days ago
Diagnostics and Error Codes
Strategy Lab diagnostics are the messages the engine shows when it cannot safely run your YAML, or when it can run but wants you to notice something about the way a rule behaved.
The plain version: errors stop the strategy. Warnings do not. But warnings still matter. A warning can explain why a trade did not fire, why a token was unavailable during warm-up, or why a field you wrote has no practical effect.
Strategy Status
The status line tells you whether the engine is allowed to trade.
Diagnostic Table
The on-chart table is meant to be read left to right:
A message usually looks like this:
ExampleEXPR_VALUE_UNAVAILABLE Long Entries > PULLBACK_ENTRY > Entry Trigger EMA_20 is not available during warm-up. Expr: CROSS_OVER(PRICE_CLOSE, EMA_20) Fix: Use NZ(EMA_20, fallback) or add a warm-up gate.
Every retained diagnostic should include a Fix: line. Known diagnostic codes use code-specific repair guidance. If a future or unknown code appears, the table falls back to documentation guidance instead of leaving you with a code and no next step.
Read the location line as the path back to your YAML:
ExampleLong Entries > PULLBACK_ENTRY > Entry Trigger
means:
ExampleIn the Long Entries section, inside the entry named PULLBACK_ENTRY, the entry_trigger_when field produced the diagnostic.
The table only retains a limited number of messages. Fix the first issues, reload or let the strategy reprocess, then read the next retained messages.
Errors vs Warnings
Warnings are not decoration. If a warning says a token was unavailable during warm-up, the engine probably used a typed fallback so the strategy could keep running. That may be exactly fine, or it may explain why an early signal stayed quiet.
Warm-Up, Lookbacks, and Unsafe Math
Most confusing diagnostics come from three different situations that look similar on the chart but need different fixes.
A token is warming up
Custom tokens from indicators can be NaN until the indicator has enough bars to calculate. For example, an EMA_20 token may not be usable at the beginning of the chart.
This can warn:
Exampleentry_trigger_when:
CROSS_OVER(PRICE_CLOSE, EMA_20)If it is safe to substitute price until the EMA exists, put the fallback directly around the token:
Exampleentry_trigger_when:
CROSS_OVER(PRICE_CLOSE, NZ(EMA_20, PRICE_CLOSE))If the rule should not even try until enough bars exist, add a warm-up gate:
Exampleentry_trigger_when:
BAR_INDEX > 20
&& CROSS_OVER(PRICE_CLOSE, EMA_20)Use this pattern for codes such as EXPR_VALUE_UNAVAILABLE when the problem is an unavailable token.
A lookback does not exist yet
On bar 0, PRICE_CLOSE[5] does not exist. On bar 3, it still does not exist.
This can warn:
Exampleentry_trigger_when:
PRICE_CLOSE > PRICE_CLOSE[5]Use NZ on the lookback value:
Exampleentry_trigger_when:
PRICE_CLOSE > NZ(PRICE_CLOSE[5], PRICE_CLOSE)Or gate the rule until the lookback can exist:
Exampleentry_trigger_when:
BAR_INDEX > 5
&& PRICE_CLOSE > PRICE_CLOSE[5]Use this pattern for EXPR_HISTORY_UNAVAILABLE.
A denominator can be zero or missing
Division, modulo, percent-from, and percent-change logic need a usable denominator. This is where SAFE_DIV belongs.
This can warn:
Exampleentry_trigger_when:
PERCENT_CHANGE(PRICE_CLOSE, PRICE_CLOSE[5]) > 0.10Put the safety inside the calculation:
Exampleentry_trigger_when:
SAFE_DIV(
PRICE_CLOSE - NZ(PRICE_CLOSE[5], PRICE_CLOSE),
NZ(PRICE_CLOSE[5], PRICE_CLOSE),
0
) * 100 > 0.10Use this pattern for EXPR_DIVISION_BY_ZERO, EXPR_MODULO_BY_ZERO, EXPR_PERCENT_BASE_INVALID, and EXPR_PERCENT_PREVIOUS_INVALID.
Do not blindly wrap everything in SAFE_DIV. It only solves denominator problems. For missing tokens or missing lookback values, start with NZ or a warm-up gate.
YAML Codes
YAML diagnostics happen while the engine parses and validates your configuration.
Example: unknown field
Example- entry_name: PULLBACK_ENTRY
entry_trigger_when: CROSS_OVER(PRICE_CLOSE, EMA_20)
entry_allocation_percent: 50
entry_order_typo: MARKETentry_order_typo should be entry_order_type.
Example: order price mismatch
Example- entry_name: MARKET_PULLBACK
entry_trigger_when: CROSS_OVER(PRICE_CLOSE, EMA_20)
entry_order_type: MARKET
entry_limit_price: PRICE_CLOSE * 0.99
entry_allocation_percent: 50Market entries do not use entry_limit_price. Either remove the price field or change the order type to LIMIT.
Expression Codes
Expression diagnostics happen while the parser compiles or evaluates a condition, price, or numeric field.
Example: wrong final type
Boolean fields need a boolean result:
Exampleentry_trigger_when:
PRICE_CLOSERepair it by using a comparison:
Exampleentry_trigger_when:
PRICE_CLOSE > EMA_20Numeric fields need a number:
Exampleentry_limit_price:
CROSS_OVER(PRICE_CLOSE, EMA_20)Repair it by returning a price:
Exampleentry_limit_price:
PRICE_CLOSE * 0.995Example: unsupported namespace
Strategy Lab expressions use parser aliases, not raw Pine namespaces:
Examplesetup_active_when:
ta.sma(close, 20) > ta.sma(close, 50)For unsupported indicator calculations such as SMA, EMA, RSI, MACD, or ATR, calculate the value in an indicator and connect it as a custom token:
Examplesetup_active_when:
SMA_20 > SMA_50Token Codes
Token diagnostics usually mean the engine could not safely resolve a built-in token, custom token, or generated state token.
Custom token names and YAML unit names become state tokens after sanitization. Keep names clear and unique:
Example- entry_name: PULLBACK_ENTRYcan create state tokens such as:
ExamplePULLBACK_ENTRY_WORKING PULLBACK_ENTRY_ACTIVE
If two names sanitize to the same base, rename one of them.
YAML unit-name collisions that would create duplicate state tokens are reported as YAML_DUPLICATE_NAME, not TOKEN_COLLISION.
Strategy and Runtime Codes
These diagnostics come from the Strategy Lab layer after YAML and expression parsing.
Diagnostic Engine Codes
These diagnostics are about the diagnostic system itself.
Repair Patterns
Use NZ when a missing value should become a fallback value:
Exampleentry_trigger_when:
PRICE_CLOSE > NZ(EMA_50, PRICE_CLOSE)Use NZ on a historical lookup when the lookup may not exist yet:
Exampleentry_trigger_when:
PRICE_CLOSE > NZ(PRICE_CLOSE[5], PRICE_CLOSE)Use SAFE_DIV when a denominator can be zero or missing:
Exampleentry_trigger_when:
SAFE_DIV(PRICE_CLOSE - NZ(PRICE_CLOSE[5], PRICE_CLOSE), NZ(PRICE_CLOSE[5], PRICE_CLOSE), 0) > 0.01Use a warm-up gate when a rule should stay quiet until the chart has enough bars:
Examplesetup_active_when:
BAR_INDEX > 200
&& PRICE_CLOSE > EMA_200Use state tokens when one unit should depend on another unit being working or active:
Exampletake_profit_gate_condition:
POSITION_ACTIVE
&& PULLBACK_ENTRY_ACTIVEUse position tokens when exits should depend on the current overall position:
Examplestop_loss_gate_condition:
POSITION_ACTIVE
&& POSITION_REMAINING_PERCENT <= 50The point is not to silence every warning. The point is to make your intent explicit enough that the engine can test the trade you meant, not whatever an early chart bar, missing token, or invalid denominator happened to produce.