Several mutation tools apply their change, wait a bounded time for the chart to settle, and then throw as though the mutation failed when the wait expires. The call succeeded; only the readiness check timed out. A caller that retries on error double-applies.
Where
src/core/chart.js, setSymbol — setSymbol() has already run by the time this throws:
const ready = await waitForChartReady(symbol);
if (!ready) throw new ClassifiedError(CATEGORIES.CHART_LOADING, `Chart did not finish loading symbol ${symbol}`);
setTimeframe has the same shape. On a slow-loading symbol both report Chart did not finish loading … while chart_get_state immediately afterwards shows the new symbol and timeframe.
src/core/indicators.js, indicator_add_from_search — a fixed wait(1500) then a before/after study diff:
if (added.length === 0) throw new ClassifiedError(CATEGORIES.API_UNEXPECTED,
`TradingView accepted "${…}" but no new study appeared`);
Observed both directions in one session: the error on a call that did add the study (it appeared after ~2s), and the identical error on a later call that added nothing. The message cannot be used to tell those apart.
Suggested fix
Distinguish "did not apply" from "applied, not yet ready". Either poll for the post-condition instead of a fixed sleep, or return a success shape that carries readiness:
{"success": true, "symbol": "…", "chart_ready": false, "note": "applied; still loading"}
For the indicator case, polling the study list for up to a few seconds rather than sleeping 1500ms would remove most of it. Whatever the shape, the contract worth stating in the tool description is: a thrown error means nothing changed. Right now it can mean either.
Several mutation tools apply their change, wait a bounded time for the chart to settle, and then throw as though the mutation failed when the wait expires. The call succeeded; only the readiness check timed out. A caller that retries on error double-applies.
Where
src/core/chart.js,setSymbol—setSymbol()has already run by the time this throws:setTimeframehas the same shape. On a slow-loading symbol both reportChart did not finish loading …whilechart_get_stateimmediately afterwards shows the new symbol and timeframe.src/core/indicators.js,indicator_add_from_search— a fixedwait(1500)then a before/after study diff:Observed both directions in one session: the error on a call that did add the study (it appeared after ~2s), and the identical error on a later call that added nothing. The message cannot be used to tell those apart.
Suggested fix
Distinguish "did not apply" from "applied, not yet ready". Either poll for the post-condition instead of a fixed sleep, or return a success shape that carries readiness:
{"success": true, "symbol": "…", "chart_ready": false, "note": "applied; still loading"}For the indicator case, polling the study list for up to a few seconds rather than sleeping 1500ms would remove most of it. Whatever the shape, the contract worth stating in the tool description is: a thrown error means nothing changed. Right now it can mean either.