Troubleshooting
The page loads but is blank
Cause: the vendor step never ran, so app/vendor/ is empty and vela.global.js cannot
resolve.
npm run vendor
# confirm the files exist
ls app/vendorapp/vendor/ is git-ignored and must be regenerated on every fresh clone. If npm install
was interrupted, run the vendor step manually.
Monaco loads but its workers 404
Cause: Monaco’s worker code constructs URLs like /vendor/vs/base/… while the AMD loader
maps vs to ./vendor/monaco. Both paths have to resolve.
scripts/copy-vendor.js mirrors monaco/ to a sibling vs/ for exactly this reason. Check
that both directories exist:
ls app/vendor/monaco app/vendor/vsIf vs/ is missing, delete app/vendor/ and re-run npm run vendor.
The blank page and the worker 404s are one missing directory
Both symptoms are app/vendor/, read at two different depths. The blank page is
vela.global.js never resolving. The 404s are the vs/ mirror being absent, because
Monaco’s worker code builds URLs like /vendor/vs/base/… while the AMD loader maps vs to
./vendor/monaco — the mirror is what makes both paths resolve, and scripts/copy-vendor.js
creates it for exactly that reason.
app/vendor/ is git-ignored, so it is missing on every fresh clone and after an interrupted
npm install. That is why neither symptom is really its own bug: the fix for both is
npm run vendor, then ls app/vendor app/vendor/monaco app/vendor/vs to confirm the files
and the mirror are both there.
Port 8080 is already in use
# Windows — find what holds the port
Get-NetTCPConnection -LocalPort 8080 -State ListenThen either stop that process or serve a different port:
npx http-server app -p 8081 -a 127.0.0.1 -c-1Verify the port is genuinely free before assuming the server started. A launcher can report success while the process it spawned has already exited.
Candles stop loading / rate-limit errors
Cause: Binance’s public endpoints are limited per IP — 6 000 request-weight per minute, and a klines call costs 2. HTTP 429 is a soft warning; HTTP 418 is a ban.
The bar cache throttles itself at 50 % of budget, and an observed 418 writes a ban marker to
localStorage under trad:binance-ban-until:v1. Subsequent launches then refuse to fetch
inside the ban window.
# check and clear the marker
# DevTools → Application → Local Storage → trad:binance-ban-until:v1Bans escalate — repeated offences step from minutes up to three days. A change of IP resets the bucket but not the behaviour that filled it. Slow down rather than routing around it. See Endpoints.
Why the failure outlives the request that caused it
Three separate mechanisms stack here, and none of them leaves evidence where you would look
for it. The budget is per IP — 6 000 request-weight per minute, 2 per klines call — so it is
shared with everything else on the same address. The bar cache throttles itself at 50 % of
budget, so a run slows down before it fails. And an observed 418 writes a ban marker to
localStorage under trad:binance-ban-until:v1, so a later launch refuses to fetch inside
the window long after the offending request is gone.
Escalation is what makes it feel permanent. Repeated offences step from minutes to three days, and a change of IP clears the counter without clearing the behaviour that tripped it. A reload will not help; time will.
pinets-cli is not found
The Python wrapper probes %LOCALAPPDATA%\Tools\node-v20 before falling back to PATH, so
it works with the portable Node the installer sets up. If neither exists:
npx pinets-cli --version
node_modules\.bin\pinets-cli.cmd --versionRe-running scripts/install.ps1 restores the expected layout.
Python tests fail on environment, not logic
Tests that call pinets-cli need Node on PATH and the CLI resolvable. The portable Node
path is derived from LOCALAPPDATA, so an unusual install location will break it.
Run the offline-only subset to separate environment problems from real failures:
.\.venv\Scripts\python.exe -m pytest -q \
tests/test_dataset.py tests/test_orchestrator_ranking.py \
tests/test_pine_lookahead.py tests/test_license_hygiene.pyA sweep produces far fewer cells than you expected
Cause: grid rewriting matches input.int( / input.float( with a single space before
the parenthesis. A declaration padded for alignment is silently skipped.
fast_len = input.int(9, "Fast EMA Length") // rewritten
atr_len = input.int(14, "ATR Length") // two spaces — NOT rewrittenIn examples/sweep_quick.yaml this is exactly why atr_len: [14] contributes one cell rather
than three. Check with --dry-run before running for real.
A skipped input collapses the dimension instead of erroring
The padded declaration is not rewritten, so it keeps the value it has in the source. The
parameter still contributes a cell — exactly one — which is why atr_len: [14] behaves the
same as a one-element list would. The config parses, the cell count still balances against
the arithmetic, and the sweep has simply lost that dimension. Nothing is logged, because
from the run’s point of view nothing went wrong.
This is what makes the symptom confusing: the YAML you wrote and the grid that executed
are both internally consistent, and the only place the loss shows up is the printed grid.
--dry-run is that place.
Hyperopt ignores my objective
Check two things:
- The name must be one of
sharpe,profit_factor,net_profit_pct,calmar,expectancy,sortino_proxy. An unrecognised name silently falls back tosharpe. direction: minimizedoes not minimise. The score function always maximises; the value only sets the Optuna study direction.
robustness_filter does nothing
It is parsed and written back to config.yaml, but sweep.py never applies it. Only
min_train_trades has any effect, and only in hyperopt.py. See
CLI reference.
The environment variables I set have no effect
.env.example names three variables that no code reads. Configuration lives in the sweep
YAML and in function arguments instead. See
Environment variables.
Results disappear after clearing storage
Saved optimizer runs live in IndexedDB, not on disk. Clearing trad:optimizer-jobs:v1 is
permanent — the runs can only be re-executed, not recovered.
# nothing to do; this is a design consequence of browser-side storageThe bar cache (trad:bars:v1) is safe to clear; it only costs bandwidth.
The test suite is red and I did not change anything
Two failures are expected and deliberate:
app/__smoke_worker_real_run.cjs— an inherited context-shape assertion that was not weakened to force the suite green.orchestrator/hyperopt.py— six tests broken by Optuna API drift.
Both are reported separately rather than fixed. See Limitations.
The docs disagree with the repository README
Expected. The README and docs/architecture.md describe an earlier phase. This site
describes the current post-Phase-F application, and where they conflict, the code and this
site are correct. See Limitations.