Where to look first
In the Run dialog, a setting it refuses shows This run can’t start yet. above the reason, and Run backtest stays disabled. On the strategy page, a run that ends without a result reads This run failed with the engine's reason and its code, or Cancelled before completion. A backtest failed notification carries the same reason.
Chat, agents and the Orbital AI connector get the same refusals; Troubleshooting for Claude and ChatGPT covers the connection's own errors.
The run stays queued
A submitted run reads Queued — waiting for the engine until the engine begins it, and holds one of the workspace's four run slots. The engine replays a few runs at a time across every workspace, so a run waits while others finish.
A submit the engine never received fails after about ten minutes with The engine never received this run — the submit was lost in transport. Run it again. A run the engine finished but Orbital could not import for six hours fails too, with a message beginning The engine finished this run, but Orbital could not import its result. To stop waiting, click Cancel run… on the strategy page; see Cancel a run.
The run quota is reached
Every workspace has two ceilings, on every plan: 4 runs queued or running at once, and 200 runs started in any rolling 24 hours. A launch over either is refused with the toast Run limit reached. The message reads this workspace already has N runs in flight — the ceiling is N at a time or N runs in the last 24h — the ceiling is N. A forward test's updates count toward both.
- The first ceiling: wait for a run to finish, or click Cancel run… on a queued or running run to free its slot.
- The second ceiling: wait. It is rolling: each run stops counting 24 hours after it started, and nothing resets it early.
In Chat and through the connector, the estimate warns first: N runs are already in flight for this workspace (the ceiling is N); Run will be refused until one finishes.
In a project where backtest pricing is on, a run the workspace cannot cover is refused with Not enough credits for this run; see Credits and billing.
The estimate was refused
The estimate on the right of the Run dialog refuses a run before anything is spent.
The data does not cover the period
The data check reads The data does not cover the period, then the engine's sentence and the code DATA_UNAVAILABLE. A run that failed this way lists each gap, such as Daily bars missing for SPY: and the dates.
Keep the period on the tape
The line under the period presets says where the tape begins, such as Daily bars are mirrored from 2016-01-04. A preset outside it is greyed and marked before the tape.
Drop the symbols the gaps name, or move the period off their dates
A ticker that had not listed yet is not a gap; see the next section.
A period that runs past the last mirrored session is not a gap: the check reads The data covers the period through that date, and the run goes to it.
A symbol listed too recently
This is a warning, not a refusal. A symbol that listed after the first session the run reads cannot supply the warm-up its indicators need. The dialog shows an amber line such as Universe: 1 of 13 symbols listed too recently to warm a 200-bar indicator by 2023-01-03. It says the symbol joins the run at its own first warm session, rather than trading from the start. It ends Start on a date or later for a window it covers end to end. The top of the run's Overview repeats it. If no symbol becomes warm inside the period, the run fails with DATA_UNAVAILABLE; start the period later.
Too many symbols, or too long a window
A static list may name at most 500 symbols; more is refused with N symbols exceeds the 500-symbol ceiling. Narrow the list in the dialog's Symbols field, or on the strategy's Input node.
The period times the universe is bounded on each bar size. The refusal reads At daily bars, N symbols allow a window of up to N months — this run asks for the two dates. Shorten the period, test fewer symbols, or run on daily bars. A preset past this bound is greyed and marked too large to run.
A setting the strategy cannot take
A Rules strategy that sells short reads This strategy sells short — run it on a margin account (toggle Margin in the launcher). Turn on Margin account; see Margin defaults.
A program does not build
The code editor's Problems tab holds the compiler's answer, and Test holds the check.
| What you see | Cause | What to do |
|---|---|---|
| Not built — the node is missing a setting | History the program reads is blank. | Set it to the deepest bar offset the program reads, then build. |
| Not built — the save was refused | A build saves the workflow first, and the save failed. | Fix what the save names, then build. |
| Compiler messages with a line and column | The source did not compile. | Click a message to jump to its line. Import every function from orbital_strategy and export exactly on_bar. |
| The source compiled, but the module failed its run-once check: and a reason | It trapped or broke a rule on a check scenario: a read deeper than its history, a stop set while flat, or a stop at or through the market. | Fix the source as the reason says and build again. |
| A sentence about a 60-second budget | The engine is still compiling. | Build the same source again in a minute; it answers at once. |
A run refuses a program changed since its last build: for a Program named Breakout it reads Program 'Breakout' changed since its last build — build the program before running it. A run stops if the program runs out of fuel on one bar; a program that exhausts the default budget needs rewriting to do less per bar. See Build and test and Fuel and limits.
A build through an agent or build_program can also return warnings; see A Program from Claude or an agent. It is refused while a deployment runs the strategy; see What a running deployment locks.
The strategy does not qualify
If a workflow is missing from the Strategies list, or Chat says it is not a strategy, its saved graph does not qualify; see Backtesting. Chat, agents and the connector give the reason after Not a strategy yet: or It does not qualify:.
- A strategy needs at least one Entry Rule node, or a Program node.
- A strategy needs an Output node declaring the signal columns (symbol, action, asOf). A missing column is named instead.
- An Input node in universe mode that names a symbol, which is ignored, so the universe would be the default preset. Set Universe preset to Custom list (use field below) and list the tickers in Custom tickers (preset = "Custom"), or for one ticker switch Source to the single-ticker asset option.
Fix the graph in the workflow editor and save it; the strategy is listed at once. A workflow never saved with an admitted graph is refused with a sentence ending save it first.
A listed strategy can still be refused at the estimate with This strategy graph is not backtestable yet. and the named diagnostics under it.
| Diagnostic | What to do |
|---|---|
| Not backtestable: the graph has no working entry rule. | Every Entry Rule failed to compile. Read each rule's own line. |
| input A is not wired or input A must come from an Indicator node | Wire an Indicator node into the rule's Indicator A port. |
| names indicator 'rsi14', which this graph does not define | Give an Indicator node that Reference name, and use each name once. |
| Sizing: risk-percent sizing needs a stop loss to size against — add one in Exit Rules. | Add a stop loss, or pick another sizing method. A trailing stop does not count. |
| Program 'Breakout' decides its own entries and exits, so it cannot share a graph with the rule cards | Delete the rule cards, or the program. |
| Program: the graph carries 2 Program nodes | Delete all but one. |
| An agent-decided strategy is not backtestable — its decisions come from a model call each tick. | A graph decided by an Agent node is for Trade, not Backtesting. |
Results look wrong
Backtests are deterministic, so a surprising result is a question about the settings, the costs or the data.
- The costs. Costs modelled under Run properties on the Report tab states what was charged. The bid-ask spread and market impact are not modelled under any profile.
- Open positions. Positions still held at the last close stay open, read Open under Closed by, and count in Net profit but not in closed-trade statistics; see Open positions at the end of a run.
- The benchmark. It is SPY unless you change it, as total return with dividends reinvested. Compare rebases its chart lines to 100 on a shared first day, but its table keeps each run's own figures.
- The data moved. The footer of the strategy's Overview says when bars were restated or corporate actions changed after the run.
- The result is too good. The deflated Sharpe ratio discounts the Sharpe for the trial count.
A forward test stopped
The strategy page's header line says what happened, and the Forward test card adds the date. Click the header line to open the last update, if there is one.
| Header line | Card | Cause |
|---|---|---|
| Forward test stopped | stopped on the date | Someone clicked Stop forward test…. |
| Forward test stopped: its window grew past what one run can hold | stopped: the window grew past what one run can hold | The window grows by a session each day, and one run's window is bounded by the bar size and the symbol count. A minute-bar strategy with many symbols reaches it first. |
| Forward test stopped: its updates were refused | stopped after two updates in a row failed | Two updates failed on two different sessions, or one was refused before it could start, such as by a gap in the data or a version or workflow that no longer exists. |
A single failed update does not stop the test; the next half-hourly check tries again, and two failures on one session wait for the next session. Each failed update sends a backtest failed notification, but the stop itself sends none.
Read the reason
The header line gives a refusal's reason; after two failed updates, the Runs view gives each one's. A window that grew too large needs a run over fewer symbols or on daily bars. For refused updates, fix what the reason names: move the period onto the data, or run the version again so a completed run exists.
Start a new test
Open the completed run and click Forward test…. The new test has its own start date.
A test that is not stopped but not updating is usually waiting: the first update lands around noon ET on the day after the start date. See How updates work.