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

  1. Ensure profiling.start(name) is called before stop(name) with the identical string.
  2. Guard: if (profiling.timerExists && profiling.timerExists(name)) before stopping (or wrap in try/catch).
  3. Pair start/stop in try/finally so failures still stop the timer exactly once.
  4. 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

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.