You have a line that looks completely normal, the code above it looks normal, and the editor is telling you a line ended when it should not have. Nothing about the message points at whitespace, which is exactly what it is about. This error is Pine objecting to the leading spaces on a line, and once you know that, it goes from baffling to a ten-second fix. The Pine Editor on TradingView is deliberately strict, which is useful once you know what it is protecting you from, but not very comforting when you need one line fixed now.
Almost everyone who hits this got the code from somewhere else. Copying out of a chat window, a documentation page, a forum post, or a Word document is the single biggest source, because all of those can silently alter leading whitespace or substitute tabs for spaces. The code is often logically correct. It is the invisible characters at the start of a line that the parser is rejecting.
What this error actually means
Pine Script uses indentation to express structure, in the same family as Python. The leading whitespace on a line is not decoration; it tells the parser whether the line begins a new statement at the current level, belongs inside the block above it, or continues an expression that started on the previous line. This error appears when the indentation of a line does not correspond to any of those three possibilities, so the parser reaches the end of a line still expecting something and has no legal way to continue.
This all happens before a single bar is processed, which is genuinely useful to know. Nothing about the symbol, the timeframe, the indicator settings, or the amount of history on the chart can affect it, so there is no point changing any of those. It is a property of the text in the editor and nothing else, which makes it one of the more deterministic Pine errors to fix: change the whitespace, recompile, done.
The code pattern that causes it
The most common form is a continuation line that is not indented, or is indented inconsistently with the line it continues. Pine allows a long expression to wrap onto multiple lines, but a wrapped line has to be indented relative to the statement it belongs to. The second most common form is the reverse: a line indented as though it belongs to a block when there is no block above it to belong to. Mixed tabs and spaces produce both, because a tab and a run of spaces can look identical while counting differently.
//@version=6
indicator("Line continuation example", overlay = true)
// A wrapped expression whose continuation is not indented. Visually it
// reads fine. To the parser, the first line ended prematurely.
longCondition = ta.crossover(ta.sma(close, 10), ta.sma(close, 30)) and
volume > ta.sma(volume, 20) and
close > open
plotshape(longCondition, "Long", style = shape.triangleup)The first line ends with the and operator, which means the expression is deliberately unfinished and something must follow. Pine is willing to accept that continuation, but only on a line indented relative to the statement. Because the next line starts at column one, the parser treats it as a brand new statement, and the previous statement is left dangling with a trailing operator. Hence: the line ended, and there was no continuation.
The smallest useful fix
//@version=6
indicator("Line continuation example", overlay = true)
// Indent every continuation line. Four spaces is conventional; what
// matters is that continuations are indented and consistent.
longCondition = ta.crossover(ta.sma(close, 10), ta.sma(close, 30)) and
volume > ta.sma(volume, 20) and
close > open
// Often clearer still: name the parts, then combine them.
trendUp = ta.crossover(ta.sma(close, 10), ta.sma(close, 30))
volumeUp = volume > ta.sma(volume, 20)
candleUp = close > open
longSignal = trendUp and volumeUp and candleUp
plotshape(longSignal, "Long", style = shape.triangleup)The first version fixes the error directly by indenting the continuation lines. The second avoids the situation altogether by giving each condition a name and combining the names on one short line, which is the version worth adopting as a habit. It is not merely tidier: a named condition can be plotted individually when you need to find out which part of a compound condition is never true, and that is a far more common debugging need than it first appears.
If the indentation looks correct and the error persists, you are almost certainly looking at mixed tabs and spaces. A tab renders as some number of columns depending on the editor, so two lines that appear aligned can be indented differently as far as the parser is concerned. Select the affected block, delete all the leading whitespace, and retype it with spaces. Adjusting it visually until it looks right is the one approach that reliably wastes time here.
How to diagnose it without guessing
Read the line above the one being flagged, not the flagged line itself. Ask a single question: does the previous line end with something that requires more to follow? A trailing and, or, comparison operator, arithmetic operator, comma, or open bracket all mean the expression is unfinished. If so, the current line is a continuation and needs to be indented. If the previous line is complete, the current line probably should not be indented at all.
Keep statements short enough not to need wrapping, and when a condition genuinely has several parts, name them separately as in the second example above. Compile after adding each logical block rather than after writing thirty lines, so the flagged line stays close to the change that caused it. These are small habits and they eliminate this error almost entirely.
Why pasted code causes this so reliably
Chat interfaces, documentation sites, and word processors all reformat text, and leading whitespace is the first casualty. Some strip it entirely so that everything lands at column one, which breaks every continuation and every block at once. Some convert runs of spaces to tabs or the reverse, which produces the invisible-mismatch version of the problem. Some insert non-breaking spaces or other Unicode whitespace that looks exactly like a space and is not one, which is the most frustrating variant because the code appears flawless.
This is a good reason to be sceptical of the copy-paste loop generally, not just for this error. When code moves through a chat window on its way to the Pine Editor, the text you paste is not guaranteed to be the text that was generated. You then debug an error that exists only because of the transport, which is a genuinely poor use of an afternoon. If a pasted script produces a whitespace error, retyping the indentation of the affected block is usually faster than investigating why.
The three whitespace rules that matter
First: a continuation must be indented relative to the statement it continues. Pine needs to distinguish "more of the previous expression" from "a new statement", and indentation is the only signal available. Any consistent indent works, and four spaces is the common convention. What breaks is a continuation at column one, because that is indistinguishable from a new statement.
Second: the body of a block must be indented consistently. Everything inside an if, an else, a for, a while, or a function body sits one level in from the line that opened it, and every line in that body sits at the same level. A line that is indented more deeply than its siblings, with nothing to justify the extra level, is not part of any block the parser recognises.
Third: never mix tabs and spaces in the same file. This is the rule that catches people who have already applied the first two correctly. Pick spaces, configure the editor to insert spaces when you press tab, and if you inherit a file with mixed indentation, normalise the whole thing before trying to fix anything else. Debugging structure while the whitespace is inconsistent means debugging two problems at once, and the invisible one will win.
Formatting as a debugging tool
Because whitespace carries meaning in Pine, deliberate formatting does real work rather than just looking neat. Group your inputs at the top, calculations beneath them, and plots and alerts in a clearly separate section at the bottom. With that arrangement, an unfinished expression stands out visually, because the next declaration is obviously a new thing rather than a continuation of the previous one. The layout gives you a baseline against which anomalies are visible.
For long function calls, put one argument per line and align the closing parenthesis with the start of the call. This makes the delimiter structure legible at a glance, so you can see whether every argument is separated by a comma and whether the call actually closed before the next statement began. It costs vertical space and it repays that cost the first time you have to find a missing comma in a call with eight named arguments.
Nested ternaries deserve particular care, because they combine the two things this error thrives on: long wrapped expressions and ambiguous continuation. A ternary nested three deep on one line is technically valid and practically unreadable. Break it across lines with the condition, the true value, and the false value each visible, or better, replace it with a switch or a sequence of named booleans. The parser will be happier and so will you in three months.
When you do hit the error and the block is a mess, do not try to repair it in place. Select the whole block, strip the leading whitespace from every line, and retype it. This sounds crude and it is dramatically faster than the alternative, because it eliminates every invisible-character possibility in one action instead of testing them one at a time.
One habit worth building is to fix only the whitespace in the edit that fixes the whitespace. It is tempting to improve the logic at the same time, since you are already in the file, but a parse error gives you a clean binary test: either the source parses or it does not. Keep that test uncontaminated. Once it compiles, make any logic change as a separate edit, and you will always know which change caused which outcome.
The same discipline applies to the surrounding code. If a script has one whitespace error, it very likely has more, because whatever damaged one line probably damaged several. Fix the first, recompile, and let the parser tell you where the next one is rather than trying to find them all by reading.
Why regenerating the script is the wrong response
This is the error where handing the whole script back to a general chat assistant does the most damage relative to the size of the actual problem. The cause is invisible characters at the start of one line. The response is typically a complete new script, with different variable names, possibly different logic, and no guarantee that the new text survives the same copy-paste journey intact. You have replaced a whitespace problem with an auditing problem.
PineScripter is our product, and the reason it fits this failure better is structural rather than clever: it edits in place and shows the change as a diff, so a whitespace repair looks like a whitespace repair, and code goes into the editor without a trip through a chat window that might reformat it. The Pine Editor still has the final say on whether it compiles, and that is the only verification that counts.
For the underlying language rule, consult TradingView documentation on script structure and line wrapping. Related reading: the broader compile-error guide, fixing "mismatched input", local-scope rules for plot, fixing "undeclared identifier".
A practical checklist before you paste again
Look at the line above the flagged one and ask whether it ends with an operator, comma, or open bracket. If it does, indent the flagged line. If it does not, remove the indentation from the flagged line. If both look right, strip and retype the leading whitespace of the whole block to eliminate tabs and stray Unicode spaces. Recompile after each single change.
Frequently asked questions
What does "end of line without line continuation" mean in Pine Script?
A line is indented in a way the grammar cannot interpret. Pine uses leading whitespace to decide whether a line starts a new statement, belongs inside the block above it, or continues an expression from the previous line. When the indentation matches none of those, the parser reaches the end of a line still expecting something.
How do I fix this error?
Look at the line above the flagged one. If it ends with an operator, a comma, or an open bracket, the expression is unfinished and the flagged line is a continuation, so indent it. If the previous line is complete, the flagged line should probably not be indented at all. If both look correct, strip and retype the leading whitespace of the whole block.
Why does pasted Pine Script cause this error?
Chat windows, documentation pages, and word processors all reformat text, and leading whitespace is the first thing they change. Some strip it entirely, some swap tabs for spaces or the reverse, and some insert non-breaking spaces that look identical to normal ones. The code is often logically correct and only the invisible characters are wrong.
Can mixing tabs and spaces cause this?
Yes, and it is the cause when the indentation looks visually correct. A tab renders as a variable number of columns depending on the editor, so two lines that appear aligned can be indented differently as far as the parser is concerned. Pick spaces, configure your editor to insert them, and normalise any file that already mixes both.
How do I avoid needing line continuations at all?
Give each part of a long condition its own name on its own short line, then combine the names. Instead of wrapping one long expression across three lines, assign trendUp, volumeUp, and candleUp separately and write longSignal = trendUp and volumeUp and candleUp. It avoids the error entirely and lets you plot each condition individually when debugging.
Indentation in Pine Script is part of the language, so this error is a grammar complaint rather than a style note. Read the previous line, decide whether the flagged line continues it or starts something new, indent accordingly, and keep the fix to whitespace alone.
Disclaimer: PineScripter is a coding tool for Pine Script development. It does not provide financial advice and does not guarantee trading profits. Always backtest strategies thoroughly and understand the risks before live trading.