Guide

"Could Not Find Function or Function Reference" in Pine Script

A function name looks familiar, but the Pine Editor cannot call it. Learn how namespaces, versions, and argument signatures cause this error.

10 min read

"Could not find function or function reference" usually appears right after you paste an example that looked credible. Pine is not saying the task is impossible. It is saying that the exact function call you supplied is not part of the language version and namespace the editor is compiling. 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.

This error is close to an undeclared identifier, but it deserves its own debugging path because the name often comes from a real function. The missing piece is usually its modern namespace, a version mismatch, or an argument pattern that does not match any available overload. Knowing which one you have prevents the classic response of asking a chatbot to regenerate a whole strategy from scratch.

What this error actually means

Pine resolves a function call by matching its full name and argument types to a documented definition. A familiar word alone is not enough. ta.sma and sma are different expressions, and a function call that worked in old code can be unavailable or moved in current Pine.

The compiler checks this before it begins evaluating bars. That is helpful because the error is deterministic. It is not caused by market data or your chart settings. If the call cannot be resolved on one chart, it cannot be resolved on another until the source code names the correct function and passes compatible arguments.

The code pattern that causes it

The most common cause in v5 and v6 is a missing namespace. Technical analysis functions live under ta, mathematical helpers under math, and string helpers under str. General-purpose code generators often produce plausible calls from language memory rather than checking Pine’s current reference.

pine
//@version=6
indicator("Function reference example")

value = rsi(close, 14)
plot(value)

The intended calculation exists, but rsi by itself does not identify the v6 built-in. The compiler cannot choose a function based on a guess. This same pattern appears with ema, highest, crossover, tostring, and abs when code leaves out ta, str, or math.

The smallest useful fix

pine
//@version=6
indicator("Function reference example")

value = ta.rsi(close, 14)
plot(value)

Adding ta tells Pine exactly which module owns the function. The existing input, variable, and plot are already valid, so a one-token change is enough. If the error persists after adding the namespace, compare the function’s arguments with the v6 reference instead of adding random parameters until the message changes.

Some failures are not namespaces. A function may have been renamed, removed, or called with an argument type it does not accept. Start by checking the //@version line. Then inspect the official signature, including whether it expects a series value, a simple length, a named parameter, or a tuple. The nearby type error can be different from this lookup error, so resolve the lookup first.

How to diagnose it without guessing

Copy only the function name and its surrounding call into a note. Ask: which namespace owns it, which Pine version is this script targeting, and what is the exact signature? Search the official manual rather than a forum excerpt. That creates a small, testable correction and avoids accidentally changing the condition that used the function.

Use a current v6 version annotation and keep built-in names fully qualified in code you reuse. If an answer provides a complete script but no Pine version, treat it as a draft, not source of truth. The more explicit your function calls are, the easier it is to audit them later.

Separate built-ins, custom functions, and signatures

A namespace error is only one form of this message. If you wrote a custom helper such as normalizeValue(source, length), Pine also needs that function defined before it is called, with the same number and types of arguments. A library function needs the required import and its qualified name. Treating all three cases as “add ta.” can turn a small lookup problem into a misleading patch.

Once the compiler finds the function, a different error may reveal an invalid argument. That is progress. For example, ta.ema expects a source and a simple integer length. If your length changes every bar, resolving the function name will correctly expose a qualifier problem next. Fix errors in that order: function lookup first, then signature, then data type, rather than changing all three at once.

Read a function call from left to right

When you inspect a function call, first identify the owner, then the function, then the arguments. In ta.ema(close, length), ta is the namespace, ema is the function, close is the source series, and length must satisfy the function’s qualifier requirement. This order matters because a compiler cannot validate a source or length until it has first resolved which ema definition you meant.

Custom functions benefit from the same discipline. Define helper functions near the top of the source, give parameters descriptive names, and keep the call signature stable. If you later change a helper from two parameters to three, update every call deliberately. Avoid naming a custom helper after a built-in, because it makes a future reader work harder to tell whether a reference belongs to your script or Pine itself.

Libraries add one more boundary. Importing a library does not make its functions global. Use the imported alias and the documented exported name. If a function reference fails after an import, verify the library version and alias before changing the calculation that depends on it. Those checks make the error local to the dependency rather than turning it into an unnecessary rewrite of your indicator.

A signature checklist before you change an expression

For a built-in function, verify four things in order: the namespace, the function name, the number of arguments, and the qualifier each argument accepts. This order prevents a common mistake where a developer changes a moving-average length or source value before confirming that they are calling the intended function. The reference signature is a contract. Once the name resolves, it tells you whether a source can vary bar to bar and whether a length must remain simple or input-qualified.

Named arguments make a call easier to audit when functions accept several optional values. They are particularly useful for visual functions and request calls, where the position of an argument can be easy to misread. Use a named argument only once, keep its value close to the call, and compare the exact parameter name with the official reference. A duplicate or invented parameter can produce a different error, but clear calls reduce the chance that the next maintainer has to guess your intent.

When you write a custom function, decide whether it needs series data, a fixed setting, or persistent state before you write the call sites. A helper that accepts a source and length should document which values are expected to change each bar. If the helper is only a wrapper around one built-in, keep it small. Over-wrapping simple calls can hide the actual Pine function that needs to be checked when an upgrade changes its signature.

Treat an error that moves from a missing function to a type or qualifier message as progress. The compiler has advanced from finding the name to validating how you use it. Preserve that signal. Fix the newly reported requirement rather than returning to a broad rewrite prompt, because the old call, namespace, and surrounding condition have now passed one layer of validation.

For future maintenance, leave a short comment only when the chosen function or parameter is non-obvious. A comment that records why a specific overload or qualifier is required prevents the same lookup question from returning during the next upgrade.

A small function-call repair is easier to review than a regenerated file

Use documentation as the boundary, not model confidence

When a chat answer invents or omits a Pine function name, the safest response is not a broad “rewrite it in v6” request. Capture the exact call, compare it with the reference, and change only the call site. That keeps a correct strategy condition, input layout, and chart output out of the repair scope.

PineScripter is designed for this constrained workflow. Its in-app lint findings can be passed through an AI fix loop, and its line-level edits make a namespace or signature correction reviewable in the Code Changes diff. It also retrieves relevant v5/v6 manual context while writing. Check the final script in the Pine Editor, especially when a corrected function exposes a later type error.

For the underlying language rule, consult TradingView documentation on built-ins. Related reading: undeclared identifier fixes, series, simple, and const values, v5-to-v6 migration details.

A practical checklist before you paste again

Check the version annotation, add the correct namespace, compare each argument with the documented signature, and compile before touching downstream logic. If the function is custom, confirm its definition appears earlier in the source and its parameters match the call.

This message is a documentation mismatch, not an invitation to replace a working script. Resolve the exact call against the current Pine reference and keep the rest of the implementation stable.

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.