◆ New — Strategy Validator, Code Fixer & Prop Compliance Checker are live. Try one free →
Home / Learn / Pine Script 'Syntax Error at Input' — What It Means and How to Fix It
Pine Script

Pine Script 'Syntax Error at Input' — What It Means and How to Fix It

Pine Script's 'syntax error at input' is the compiler telling you it stopped being able to parse your code at a specific token — and the real mistake is often on an earlier line. This guide covers the four causes behind almost every instance: a missing //@version directive, broken indentation or line-wrapping, unbalanced brackets, and invisible characters pasted in from the web or AI chat windows, each with the wrong version and the corrected Pine v6 shown side by side. Educational material only, not financial advice; a script that compiles is merely a script that compiles — it says nothing about whether the logic is sound or the strategy has an edge, and trading carries a real risk of loss.

What does 'syntax error at input' mean in Pine Script?

'Syntax error at input X' means the Pine compiler was parsing your script token by token and, at token X, hit something that cannot legally appear there — so it gave up. It is a parse error, not a logic error: the compiler is not saying your idea is wrong, it is saying it literally cannot read the file past that point. Crucially, the token it names is where parsing broke, which is frequently one line after where the actual mistake lives — an unclosed parenthesis on line 12 typically produces a syntax error report pointing at line 13.

In practice, nearly every instance of this error traces back to one of four causes: (1) a missing or wrong //@version directive, so your modern code is being read by an ancient parser; (2) indentation or line-wrapping that violates Pine's whitespace rules, which are stricter than most languages; (3) unbalanced parentheses, brackets, or a dangling operator; or (4) invisible characters — smart quotes, non-breaking spaces — pasted in from a website or an AI chat window. This last cause has become dramatically more common now that a large share of Pine code arrives via copy-paste from LLM outputs.

The variant message syntax error at input 'end of line without line continuation' is the same failure with extra information: the parser reached the end of a line while it still expected more tokens — the classic signatures are a line ending in an operator, a comma, or an unclosed (.

Read the reported line, then read the line above it, and work through the four causes in the order above — that order matches how often each one is actually responsible. The sections below take them one at a time, with the broken version and the fix shown together.

Check the //@version directive before anything else

If your script has no //@version annotation, TradingView compiles it with the version 1 parser — a dialect from 2013 that predates input.int(), the ta.*/math.*/str.* namespaces, switch, method, and nearly everything else in modern Pine. The result is that perfectly good v6 code produces a wall of syntax errors that have nothing to do with your logic. The same applies when the annotation says //@version=4 but the body uses v6-only constructs.

This is the single most common failure mode in AI-generated Pine, because models sometimes emit the body of a script without the directive, or a user copies everything below the first line. Here is the broken shape:

// ❌ Wrong — no //@version directive, so the v1 parser reads this
// and fails on the very first modern construct it meets.
length = input.int(20, "Length")
plot(ta.sma(close, length))

And the fix — the directive on line one, before anything else including comments about the script, plus a declaration statement:

//@version=6
// Educational only — validate before trading; not financial advice.
indicator("SMA example", overlay = true)
length = input.int(20, "Length")
plot(ta.sma(close, length))

Two related rules: the directive must be spelled exactly //@version=6 (no spaces inside), and every script needs exactly one declaration call — indicator() for visual studies or strategy() only when the script actually places entries and exits. A missing declaration produces its own error, but a misplaced one (indented, or below other statements in odd ways) can surface as a syntax error too. When a script that "looks fine" refuses to compile, confirming line 1 takes five seconds and resolves a remarkable share of cases.

Indentation and line wrapping: Pine's strictest rules

Pine defines code blocks by indentation, like Python, but with a rigid convention: the body of an if, for, while, switch, or function definition must be indented by exactly four spaces (or one tab) per nesting level. Forget the indent and the parser sees a statement where it demanded a block:

// ❌ Wrong — the body of the if is not indented,
// so the parser errors at 'label.new'
if ta.crossover(close, ta.sma(close, 20))
label.new(bar_index, high, "Cross")

The corrected script, with the body indented and the signal gated on a confirmed bar so it doesn't fire on a still-forming candle:

//@version=6
// Educational only — validate before trading; not financial advice.
indicator("Cross label", overlay = true)
crossUp = ta.crossover(close, ta.sma(close, 20))
if crossUp and barstate.isconfirmed
    label.new(bar_index, high, "Cross")

Line wrapping is the mirror-image trap. You may split a long statement across lines, but the continuation must be indented by an amount that is not a multiple of four — otherwise the parser reads it as the start of a new local block:

// ❌ Wrong — the continuation is indented exactly 4 spaces,
// so Pine treats it as a new block, not a continued expression
signal = ta.crossover(close, ta.sma(close, 50)) and
    close > ta.sma(close, 200)
//@version=6
// Educational only — validate before trading; not financial advice.
indicator("Wrapped condition", overlay = true)
signal = ta.crossover(close, ta.sma(close, 50)) and
     close > ta.sma(close, 200)
plotshape(signal and barstate.isconfirmed, style = shape.triangleup, location = location.belowbar)

Five spaces on the continuation — one more than a block indent — is the conventional choice. Mixing tabs and spaces in the same file compounds all of this invisibly, so pick one and stay with it.

Unbalanced brackets, dangling operators, and errors that point at the wrong line

When you leave a parenthesis unclosed, the parser doesn't fail at the opening ( — it keeps consuming tokens hoping for the ) and only errors when it hits something impossible, usually on the next line. So the reported location is systematically misleading:

// ❌ Wrong — the missing ')' is on the first line,
// but the error is reported at 'plot' on the second
ma = ta.sma(close, 20
plot(ma)
//@version=6
// Educational only — validate before trading; not financial advice.
indicator("Balanced", overlay = true)
ma = ta.sma(close, 20)
plot(ma)

The same displacement happens with a dangling operator (x = a + at end of line with nothing legal following), a trailing comma inside a call, or a ternary missing its : branch — Pine's cond ? a : b requires both arms. When the message is end of line without line continuation, suspect exactly these: the parser needed one more operand or bracket and the line ended first.

The reliable diagnostic is bisection: comment out the bottom half of the script and recompile. Error gone? The mistake is in the commented half; restore half of it and repeat. Because Pine scripts are typically a few hundred lines, three or four iterations isolate the offending statement, at which point counting brackets by eye is feasible. Two further checks worth automating into habit: first, in the TradingView editor, place the cursor next to each bracket — the editor highlights its partner, and an unhighlighted bracket is your culprit. Second, retype (don't re-paste) the suspect line. Code copied from blogs, PDFs, or chat interfaces often carries typographic quotes (“” instead of ") or non-breaking spaces that render identically to normal ones but are different bytes — invisible to you, fatal to the parser. Retyping launders them out.

A repeatable debug workflow — and why compiling is only step one

Pulling the causes together, here is the checklist to run whenever syntax error at input appears, in order of likelihood and cheapness:

  1. Line 1: is //@version=6 present, exact, and first? Does the body's syntax match the declared version?
  2. The reported line and the one above it: unclosed bracket, trailing operator, trailing comma, ternary missing :.
  3. Whitespace: block bodies indented exactly four spaces; wrapped continuations indented a non-multiple of four; no tab/space mixing.
  4. Invisible characters: retype pasted lines; watch for smart quotes and non-breaking spaces from web or AI sources.
  5. Bisect: comment out half the script, recompile, and narrow until the offending statement is isolated.

This workflow resolves the overwhelming majority of cases in minutes. For AI-generated scripts specifically, expect clusters of these errors: a model that drops the version directive usually also produces v5-style and v6-style constructs mixed together, so fixing the first reported error often reveals a second and third. That is normal — the parser can only report the first point of failure, not all of them at once.

And a closing note in the spirit of honesty: a script that compiles has cleared the lowest bar there is. The parser checks grammar, not meaning. Repainting request.security() calls, signals evaluated on unconfirmed bars, risk inputs that are declared but never wired into an exit — all of these compile without complaint and quietly invalidate whatever a backtest appears to show. Once your script compiles, the real validation work starts: confirm the logic doesn't repaint, that alerts fire only on confirmed bars, and that every declared stop actually reaches a strategy.exit(). Automated checking — like the ForexCodes validator and Code Fixer — exists precisely for that second, harder layer. None of this is financial advice, and no compiling script, however clean, implies a profitable one. Trading carries a real risk of loss.

Key takeaways

Educational only — not financial advice. Trading involves substantial risk of loss.

Catch the bug that compiles.Run auditGet Pro