/Documentation

Execution

Logs & Debugging

Last updated April 20, 2026

Norena writes a structured log entry for every meaningful event during strategy execution. This page explains what each log type means, how to read the Trade Detail Modal, and how to diagnose common issues.

Log Overview

Norena writes structured log entries to project_logs for every meaningful event during strategy execution. Logs are displayed in real time in the Logs tab of each project, with the most recent entries at the top.

Most log entries include a meta object with contextual fields like run_id,symbol, and exchange. Trade-specific entries additionally include a full detail_json payload with structured data that powers the Trade Detail Modal.

Log Levels

LevelMeaningColor in UI
infoNormal operation — run started/finished, no-trade result, connectivity OK, trade trigger/executed.White / default
warnNon-fatal issue — stale klines, max trades reached, weekend skip, advanced logging diagnostics.Yellow
errorExecution failure — strategy threw an exception, wallet credentials invalid, Binance connectivity failed.Red

Structured Log Types

Trade logs include a detail_json field with a kind discriminator. The two kinds produced by the runner are:

trade_trigger

Written immediately when HP.buy() or HP.sell() is called, before the order is placed. Contains the decision-time snapshot:

  • side: "BUY" or "SELL"
  • symbol: The trading pair
  • interval: Primary timeframe of the strategy
  • price_at_trigger: Mark price at the exact moment the decision was made
  • trigger.rows: Ordered array of every condition evaluated, with values and results
  • trigger.context.position_before: Open position state before the trade (qty, entry price, entry time)

trade_executed

Written after the order fills. Contains the execution result:

  • order_type: Always "MARKET"
  • filled_qty / filled_price: Actual fill details from the exchange
  • status: "FILLED", "PARTIALLY_FILLED", or "REJECTED"
  • exchange_order_id: Binance order ID (live mode only)
  • fees: Amount and asset (e.g. 0.0000149 BNB)
  • slippage: Absolute and percentage difference between trigger price and fill price
  • position_after: Position state after the fill

Linking trigger and executed logs

The trade row in project_trades stores both trigger_log_id andexecuted_log_id, linking the two log entries to the trade. The Trade Detail Modal uses these IDs to fetch and display both log entries together.

Reading the Logs Tab

The Logs tab streams entries in reverse-chronological order. Key entries to look for:

Log messageWhat it means
Run started.The runner has begun a new tick for this project.
Run finished OK.All symbols were evaluated without errors.
Result: No trade conditions metNormal — the strategy ran but no HP.buy/sell was called.
Result: BUY signal detectedHP.buy() was called. A TRADE_TRIGGER entry follows.
Trade executed: BUY BTCUSDTOrder filled. A TRADE_EXECUTED entry with slippage data follows.
Klines not ready yet for BTCUSDT 1hThe kline cache hasn't bootstrapped yet. Wait a few minutes after project start.
Stale klines for BTCUSDT (Xm old)The kline manager is lagging. The tick was skipped to avoid stale signal.
Run skipped: outside trade hoursThe current UTC time is outside the configured trade window.
Run skipped: weekend trading disabledToday is Saturday or Sunday UTC and Disable Weekends is on.
Live mode requires valid API credentialsWallet credentials are missing or empty. Fell back to paper mode.
Strategy error for BTCUSDT: ...The strategy threw an exception. The error message follows.

Trade Detail Modal

Click any row in the Positions tab to open the Trade Detail Modal. This is the most powerful debugging tool available for understanding exactly why a trade happened and how it was filled.

The modal shows two columns:

  • Left — TRADE_TRIGGER: The condition table from decision time. Every boolean comparison evaluated when HP.buy/sell was called, with its runtime value, rule string, and pass/fail result.
  • Right — TRADE_EXECUTED: The fill details — price, quantity, fees, order status, exchange order ID, and slippage breakdown.

Reading the Condition Table

The condition table in the Trade Detail Modal shows exactly what was true or false when the trade was placed. Here's how to read it:

Row typeAppearanceMeaning
Leaf conditionHas a condition label, value, rule (e.g. "RSI(14) < 30"), and a ✓ or ✗A single boolean comparison. Green = passed, red = failed.
Context rowRule column shows "—", no pass/fail indicatorDisplay-only row showing a reference value (e.g. EMA(50) = 66800). Not a condition itself.
AND/OR group headerGrouped sub-rows with indentationSub-conditions inside a compound AND/OR. Each sub-row shows its individual result.
AND/OR summary row"AND" or "OR" with the group's overall resultThe runtime result of the compound expression. This is the fact — it is never inverted.
System condition"Active Window (UTC)" or "Max Trades Today"System-level guard conditions that were checked before the strategy code ran.

Else branch behavior

When a trade fires from an else branch, the condition table shows thenegated form of the entry condition — reflecting why the else branch was entered rather than the if branch. For example, if the if condition was "RSI(14) < 30" and the else fired, you'll see "RSI(14) ≥ 30" in the table. This is accurate — it shows the condition that was NOT met, causing the else path to be taken.

Common Errors

ErrorCauseFix
Strategy execution timed out after 5000msStrategy code ran for more than 5 seconds. Usually caused by an infinite loop or deeply nested computation.Simplify the strategy. Check for while loops or recursive patterns. Each run should complete in well under 1 second.
Strategy error: X is not definedA block's generated code references a function that doesn't exist in the sandbox.Re-compile the strategy. If the error persists, the block may be using an outdated generator. Replace it with a fresh block from the toolbox.
Legacy hp_trade_buy block detectedAn old-format BUY or SELL block from a previous version is still in the workspace.Remove the legacy block and replace it with the current BUY or SELL block from the Trading category.
Live mode requires valid API credentials — falling back to paperMode is set to Live but the wallet is missing or has empty credentials.Set up a wallet in Settings → Wallets and select it in the project Settings tab.
Binance connectivity check failed: ...The connectivity probe to Binance failed (bad API key, network issue, IP not whitelisted).Verify your API key is active on Binance, has Spot Trading permission enabled, and is not IP-restricted to an address that doesn't match the Norena server.
[SECURITY] Credential decryption failedThe stored wallet credentials could not be decrypted (e.g. re-encryption needed after a key rotation).Re-save the wallet in Settings → Wallets to re-encrypt the credentials with the current key.
Klines not ready yet for BTCUSDT 1hThe kline bootstrap hasn't completed yet for this symbol and timeframe.Wait 1–2 minutes after first starting the project. The bootstrap runs automatically in the background.
Stale klines for BTCUSDT (Xm old)The kline manager hasn't updated the cache within the 3-minute staleness threshold.Check the server status. If the runner is healthy, this is usually a transient issue that resolves on the next tick.
No generated_js found. Skipping run.The project has never been compiled, or was saved without compiling.Open the project, make any change in the editor, and click Compile.
Indicators return NaNInsufficient data for the calculation (fewer bars loaded than the indicator period requires).Check that the primary timeframe has enough history. For slow timeframes like 1d, the backtest or live cache may not have enough bars for long-period indicators. Reduce the period or switch to a faster timeframe.