Skip to content

Four valid request.security forms refused: lookahead from a variable, '' timeframe, [] on a requested value in a nested request, an uncalled wrapper #294

Closed

Description

@letiep97

Summary

Each script below is valid v6 and is refused at translation. Each has a control that differs in one place and translates and runs.

# Pine form Refusal
1 lookahead = mode, with mode chosen from an input.bool ANALYZER request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off.
2 timeframe = '' ANALYZER request.security: invalid timeframe literal ''.
3 ta.ema(base[1], 5) inside a second request, where base is the result of a first request CODEGEN request.security helper call history is only supported in the payload itself
4 a function that wraps request.security and is never called CODEGEN Unknown variable 'expr'

Versions

pineforge-codegen 1.9.1, and main at c1cc532 (after #290) run from source: same refusals. Controls were built with pineforge-engine v1.9.1 (fc0a2df), Apple clang 17.0.0, macOS 15.8 arm64, and run on BTCUSDT 1h bars from 2024-01-01 to 2024-03-01. The refusals come from the front end, so they should not depend on the platform.

Reproduction

1. lookahead from a variable

//@version=6
strategy('repro')
useLookahead = input.bool(true, 'Lookahead')
mode = useLookahead ? barmerge.lookahead_on : barmerge.lookahead_off
daily = request.security(syminfo.tickerid, 'D', close[1], lookahead = mode)
plot(daily)

ANALYZER 5:71 request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off.

Control, lookahead = barmerge.lookahead_on: translates and runs.

2. Empty timeframe

//@version=6
strategy('repro')
same = request.security(syminfo.tickerid, '', close)
diff = same - close
// @pf-trace diff=diff
plot(same)

ANALYZER 3:43 request.security: invalid timeframe literal ''. Expected Pine TF format like '1', '15', '1H', '1D', '15S'.

Control, timeframe.period in place of '': translates, and diff is 0 on all 1,441 bars.

3. [] on a requested value inside a second request

//@version=6
strategy('repro')
base = request.security(syminfo.tickerid, 'D', close)
smooth = request.security(syminfo.tickerid, '240', ta.ema(base[1], 5))
plot(smooth)

CODEGEN 1:1 request.security helper call history is only supported in the payload itself

Control, ta.ema(base, 5): translates and runs. The refusal points at line 1, column 1, not at the call. This is a different form from #287: no user function is involved.

4. A wrapper function that is never called

//@version=6
strategy('repro')
fetch(sym, tf, expr) => request.security(sym, tf, expr)
daily = request.security(syminfo.tickerid, 'D', close[1])
plot(daily)

CODEGEN 3:51 Unknown variable 'expr' — not a PineForge builtin or a declared variable.

Control, without the fetch line: translates and runs. When the wrapper is called, daily = fetch(syminfo.tickerid, 'D', close[1]), the script translates and runs, so only the uncalled definition fails.

Expected

All four translate and give the controls' values.

  1. lookahead takes a "simple" value, and a ternary of an input is "input", which is weaker and accepted (qualifiers, lookahead). Checked on TradingView (BINANCE:BTCUSDT 1h): the script compiles and runs, with no error or warning.
  2. An empty string as the timeframe means the chart's timeframe, the same as timeframe.period (timeframes). Checked on TradingView (BINANCE:BTCUSDT 1h): the script compiles and runs; diff is 0 on every bar.
  3. A request whose expression depends on another request evaluates that request in its own context (nested requests), and [] applies to any series (history-referencing operator). If the form cannot be supported, a refusal located at the call would help. Checked on TradingView (BINANCE:BTCUSDT 1h): the script compiles and runs, with no error or warning.
  4. A function that is never called does not affect the script (user-defined functions). Checked on TradingView (BINANCE:BTCUSDT 1h): the script compiles and runs, with no error or warning, and daily has the same values as in the control.

Workaround

  1. Write two request.security calls with literal lookahead values and pick the result with the input: daily = useLookahead ? dailyOn : dailyOff translates and gives the same values as the control.
  2. Use timeframe.period.
  3. None found that keeps the same values.
  4. Remove the unused wrapper.

Activity

  1. luisleo526 commented on Nov 1, 2026

    @luisleo526
    Contributor

    Thank you for the detailed report. We are checking each case against TradingView's behaviour and our source, and will post a result for each case in this issue by the end of 2026-11-03 (UTC). If a case needs longer, we will say so here with the reason.

  2. luisleo526 commented on Nov 3, 2026

    @luisleo526
    Contributor

    Thank you for the four scripts, their controls and the TradingView checks. This is the result for each case on the released pineforge-codegen 1.10.0. None of the four is fixed in 1.10.0; the fix is planned for the next release (1.10.1), as the 1.10.0 release notes list for this issue.

    # Case Result on 1.10.0 Matches TradingView?
    1 lookahead = mode, with mode chosen from an input.bool Still refused: request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off. No: TradingView accepts it (an input-qualified value is accepted)
    2 timeframe = '' Still refused: request.security: invalid timeframe literal ''. No: '' means the chart's timeframe on TradingView, as timeframe.period does
    3 ta.ema(base[1], 5) inside a second request, where base is the result of a first request Still refused: request.security helper call history is only supported in the payload itself (reported at line 1, column 1, not at the call) No: valid on TradingView
    4 a function that wraps request.security and is never called Still refused: Unknown variable 'expr'; when the wrapper is called the script translates and runs No: an uncalled function does not affect a script on TradingView

    All four are defects, not intended limits. The fix is planned for the next release (1.10.1); the issue stays open until it is released. Until then your workarounds hold (two requests with literal lookahead values and a selection; timeframe.period; removing the unused wrapper); for case 3 no workaround that keeps the values has been found.

  3. luisleo526 commented on Nov 6, 2026

    @luisleo526
    Contributor

    Status: all four cases are fixed on main: each script now translates, builds and runs. The fixes ship in the next release; the issue stays open until they are released.

    Checked with the code of main at 5b72a0c and the engine at d398279, on Linux aarch64: each script of the issue was translated, the generated C++ was built against the engine and run on BTCUSDT 1h bars from 2024-01-01 to 2024-03-01 (1,441 bars). "Result on 1.10.0" is the result in our comment of 2026-11-03. The TradingView results are the ones the report gives.

    # Case TradingView Result on 1.10.0 main at 5b72a0c Matches TradingView?
    1 lookahead = mode, with mode chosen from an input.bool compiles and runs refused: request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off. translates, builds and runs; daily equals the control's (lookahead = barmerge.lookahead_on, the default input) on all 1,441 bars Yes
    2 timeframe = '' compiles and runs; diff is 0 on every bar refused: request.security: invalid timeframe literal ''. runs; diff is 0 on all 1,441 bars Yes
    3 ta.ema(base[1], 5) inside a second request, where base is the result of a first request compiles and runs (the report prints no value) refused: request.security helper call history is only supported in the payload itself translates, builds and runs; smooth has its first value on bar 27 Yes: it is accepted, as on TradingView. The values are not compared: the report prints no TradingView value for this script
    4 a function that wraps request.security and is never called compiles and runs; daily has the control's values refused: Unknown variable 'expr' runs; daily equals the control's (without the wrapper) on all 1,441 bars Yes

    Not run: x86 and macOS.

  4. luisleo526 commented on Nov 8, 2026

    @luisleo526
    Contributor

    Update: today's check confirms that all four reported forms translate, build and run on main.

    Checked on 2026-11-08 on codegen main at 7d7681dc with engine main at 755e6658, on the 1,441-bar BTCUSDT 1h sample.

    # Case Result on main today Change Matches the value the issue prints?
    1 lookahead = mode, with mode chosen from an input.bool daily equals the lookahead_on control on all 1,441 bars with the default input #327 (08261a24) Yes
    2 timeframe = '' diff is 0 on all 1,441 bars #327 (08261a24) Yes
    3 ta.ema(base[1], 5) inside a second request, where base is the result of a first request Translates, builds and runs; smooth first has a value on bar 27 and is 61936.8757259202 on bar 1440 #327 (08261a24) Acceptance matches; no TradingView value is printed for comparison
    4 a function that wraps request.security and is never called daily equals the control without the wrapper on all 1,441 bars #327 (08261a24) Yes

    Case 3's numbers describe today's PineForge result only. The issue prints no TradingView value for it. Acceptance also does not mean there are no diagnostics: the scripts still report the applicable lookahead, EMA start-up and visual-only plot warnings.

    This is fixed on main and ships in 1.11.0, whose publish target is 2026-11-10. This issue will be closed when that release is published.

  5. luisleo526 commented on Nov 9, 2026

    @luisleo526
    Contributor

    Fixed in v1.11.0: all four request.security forms in this issue are accepted and run in v1.11.0. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions