NativeScript/NativeScript · error · Error
No timer started: ${name}
Error message
No timer started: ${name} What it means
profiling.stop(name) looks up the timer registered by a prior profiling.start(name); if no timer with that name exists it throws 'No timer started: <name>'. Timers live in a module-level registry, so stop() must be paired exactly with a start() that ran earlier in the same session.
Source
Thrown at packages/core/profiling/index.ts:60
info.currentStart = time();
info.runCount++;
} else {
info = {
totalTime: 0,
count: 0,
currentStart: time(),
runCount: 1,
};
timers[name] = info;
profileNames.push(name);
}
}
export function stop(name: string): TimerInfo {
const info = timers[name];
if (!info) {
throw new Error(`No timer started: ${name}`);
}
if (info.runCount) {
info.runCount--;
if (info.runCount) {
info.count++;
} else {
info.lastTime = time() - info.currentStart;
info.totalTime += info.lastTime;
info.count++;
info.currentStart = 0;
}
} else {
throw new Error(`Timer ${name} paused more times than started.`);
}
return info;
}View on GitHub (pinned to 6800aefa65)
Solutions
- Ensure profiling.start(name) is called before stop(name) with the identical string.
- Guard: if (profiling.timerExists && profiling.timerExists(name)) before stopping (or wrap in try/catch).
- Pair start/stop in try/finally so failures still stop the timer exactly once.
- Verify no duplicate module instances are splitting the timer registry.
Example fix
// before
try {
profiling.start('render');
doWork();
} finally {
profiling.stop('render'); // throws if start never ran
}
// after
profiling.start('render');
try {
doWork();
} finally {
if (profiling.timerExists('render')) profiling.stop('render');
} Defensive patterns
Strategy: try-catch
Validate before calling
import * as profiling from '@nativescript/core/profiling';
//
if (!profiling.timerExists || profiling.timerExists(name)) { // guard if API available
profiling.stop(name);
} Type guard
function canStop(name) {
try { profiling.stop(name); return true; } catch { return false; }
} Try / catch
try {
profiling.stop(name);
} catch (e) {
if (String(e.message).startsWith('No timer started:')) {
// ignore or start+stop a no-op timer
} else throw e;
} Prevention
- Pair every start() with exactly one stop() using a shared name constant.
- Put stop() in a finally block only after start() succeeded.
- Extract timer names into constants to avoid typos.
- Never stop the same timer twice.
When it happens
Trigger: Calling profiling.stop('x') without a matching profiling.start('x'); calling stop twice after start's runCount is exhausted; typos in the timer name; profiling enabled via __NS_PROFILE__ flags but stop() invoked for a name never registered.
Common situations: Conditional start() paths skipped (early return, error thrown) while stop() runs unconditionally; renaming a timer in one place but not the other; module loaded twice (different paths) so the registry is split.
Related errors
AI-assisted analysis of NativeScript/NativeScript@6800aefa65 (2026-08-30).
Data as JSON: /api/errors/35fc35bc32a6e6a2.
Report an issue: GitHub.