Appearance
Errors and debugging
Why did your script stop and draw nothing? An error on any one bar stops the whole run, and the chart then shows the error and nothing else, as TradingView does. The message names the bar and, where it can, the line: guard the read that failed so it can't fail on any bar.
pine
//@version=6
indicator("Third-last swing high", overlay = true)
var array<float> swings = array.new<float>()
float ph = ta.pivothigh(high, 5, 5)
if not na(ph)
swings.push(ph)
// unguarded, get(-3) stops the run at bar 0, before any swing
plot(swings.size() >= 3 ? swings.get(-3) : na, "Third-last")What an error does
An error stops the run where it happens, and nothing the run made is shown: no plots, no drawings, no tables and no strategy report. It doesn't matter which bar it was, whether the failing line sits in a function, or whether it ran inside a request.security expression on another symbol's bars. One bad bar out of thousands stops it all, so a script that ran yesterday can stop today on a bar it hasn't met before.
Without the guard, the example above stops on its first bar. The run's error reads Bar 0 (line 7): Array index -3 out of bounds (size 0): the bar's index from 0, the line, then what went wrong. The Script Editor's console lists it at line 7 as Array index -3 out of bounds (size 0) (bar 0), and marks the line:
pine
//@version=6
indicator("Third-last swing high, unguarded", overlay = true)
var array<float> swings = array.new<float>()
float ph = ta.pivothigh(high, 5, 5)
if not na(ph)
swings.push(ph)
plot(swings.get(-3), "Third-last")Stopping it yourself
runtime.error("message") stops the run with your message, which suits a setting that makes no sense, such as a fast length above a slow one. runtime.error has an example. AmenoScript's input.check(condition, message) does the same on the first bar for a check on the inputs. See Inputs with ids, ranges and checks.
Errors you'll meet
| Message | What happened | What to do |
|---|---|---|
Array index 5 out of bounds (size 3) | An index past either end of an array | Check size() first, as the example does |
array.first() called on an empty array | first, last, pop or shift on an empty array | Check size() > 0 |
array.new size 100001 exceeds the 100000-element limit | An array or matrix past 100,000 elements | Drop the oldest elements as you add new ones |
Stack overflow: maximum call depth exceeded | A function calling itself more than 64 deep (AmenoScript only, since Pine refuses recursion) | Turn the recursion into a loop |
Pine v6 strict (line 4): ... | Something TradingView refuses to compile, found by strict Pine | Rewrite it, or see Pine compatibility |
Expected '(' here, found 'float' | A line the parser can't read | Fix the line the editor marks |
Warnings
A warning doesn't stop the run: the script runs and draws, and the Script Editor marks the line. Read each one, since most say a value isn't what you think it is.
| A warning that says | Means |
|---|---|
This declares a new x for this block, and the x outside it keeps its value | x = ... inside a block made a second x, TradingView's CW10013. Write x := ... to change the first |
This loop's i is its own, and the i outside it keeps its value | A loop counter shares a name with a variable outside the loop |
ta.sma runs only on the bars this branch runs, so its history fills late | A ta.* call inside an if or a ternary, TradingView's CW10003. See State in functions and branches |
ta.sma in a loop keeps one state for all its passes | A ta.* call inside a loop |
plot's linewidth must be input ... TradingView refuses it | A value that changes from bar to bar where TradingView needs one fixed when the script starts. It runs here and fails there |
Leak warning: ... | Something that reads differently live than on history, such as varip or lookahead_on. AmenoScript refuses these. See Leak-safe runs |
Running on the interpreter, which is much slower: ... | The compiler couldn't take the script. See Performance |
Limits
A run here works within these limits. Some are TradingView's and some are ours.
| Limit | Here | On TradingView |
|---|---|---|
| A loop's passes | 100,000 each time a for or while starts. Past that the loop ends early, with no error and no warning | No count: a loop that runs too long stops the script |
| An array or matrix | 100,000 elements | 100,000 elements |
| Drawings | The newest of each kind, 50 by default, and a max_*_count above 500 is taken as given: see Drawings | The newest 50 by default, 500 at most |
| History | close[6000] reads 6,000 bars back, and max_bars_back() does nothing | A read past the buffer stops the script unless max_bars_back makes room |
| Time | No limit on a chart | A script past 40 seconds stops, with error RE10110 |
| Recursion | 64 calls deep, AmenoScript only | Refused |
| Requests inside requests | 8 deep; a deeper one reads na with a warning |
WARNING
A loop that would pass more than 100,000 times stops quietly at 100,000, and the script goes on with what it has. A sum or a search over that many values comes out short with nothing to say so. Keep loops well under the limit, or count the passes and check.
Two of these run the other way from TradingView: no time limit and unlimited history mean a script that runs here can stop on TradingView. Keep a script you'll take there within its limits.
Seeing what a script does
log.info(), log.warning() and log.error() are accepted and do nothing, on every engine: there is no Pine Logs pane here. To see a value, show it on the chart.
pine
//@version=6
indicator("Look inside", overlay = true)
float atr = ta.atr(14)
float stop = close - 2 * atr
// in the data window only, so it doesn't move the price scale
plot(atr, "ATR", display = display.data_window)
plot(stop, "Stop")
if barstate.islast
string say = "ATR " + str.tostring(atr, format.mintick)
say += "\nstop " + str.tostring(stop, format.mintick)
label.new(bar_index, high, say)- A plot shows a value on every bar. With
display = display.data_windowit shows only in the data window, out of the chart's way. - A label on the last bar shows several values at once, as text.
- A table holds a grid of values in a corner of the pane, the way to show the contents of an array. See Drawings and tables.
plotchar()marks the bars where a condition is true, which shows when a branch runs.runtime.errorstops at the first bar where something is wrong and says what: build its message withstr.tostringof the values you need.
See also
- runtime.error, the call that stops a run
- Pine compatibility, what strict Pine refuses and why
- Performance, when a script is slow rather than wrong
- Drawings and tables, labels and tables for a look inside