{"record":{"id":"862dbb2e9b4fbb39","repo":"NativeScript/NativeScript","slug":"timer-name-paused-more-times-than-started","errorCode":null,"errorMessage":"Timer ${name} paused more times than started.","messagePattern":"Timer (.+?) paused more times than started\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/profiling/index.ts","lineNumber":74,"sourceCode":"export function stop(name: string): TimerInfo {\n\tconst info = timers[name];\n\n\tif (!info) {\n\t\tthrow new Error(`No timer started: ${name}`);\n\t}\n\n\tif (info.runCount) {\n\t\tinfo.runCount--;\n\t\tif (info.runCount) {\n\t\t\tinfo.count++;\n\t\t} else {\n\t\t\tinfo.lastTime = time() - info.currentStart;\n\t\t\tinfo.totalTime += info.lastTime;\n\t\t\tinfo.count++;\n\t\t\tinfo.currentStart = 0;\n\t\t}\n\t} else {\n\t\tthrow new Error(`Timer ${name} paused more times than started.`);\n\t}\n\n\treturn info;\n}\n\nexport function timer(name: string): TimerInfo {\n\treturn timers[name];\n}\n\nexport function print(name: string): TimerInfo {\n\tconst info = timers[name];\n\tif (!info) {\n\t\tthrow new Error(`No timer started: ${name}`);\n\t}\n\n\tconsole.log(`---- [${name}] STOP total: ${info.totalTime} count:${info.count}`);\n\n\treturn info;","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/NativeScript/NativeScript/blob/6800aefa6511d23ddad8beb38ccc8541c5e91628/packages/core/profiling/index.ts#L56-L92","documentation":"The profiling module tracks timers created with timer(name)/start(name). stop(name) increments internal pause accounting; throwing here means stop() (or pause accounting) was called more times than the timer was started, so the timing state is inconsistent. It guards against unbalanced start/stop pairs in profiling code.","triggerScenarios":"Calling stop(name) (via countersProfileFunctionFactory-wrapped functions) more times than start(name) was called for the same timer name, e.g. wrapping a function whose factory calls stop twice, or stopping a timer whose start threw.","commonSituations":"Instrumenting a code path where an early return or exception bypasses one start but a finally block still stops; copy-pasted stop() calls; wrapping recursive functions so stop fires per recursion level more than start.","solutions":["Ensure every stop(name) has a matching start(name) before it","Check that countersProfileFunctionFactory-wrapped functions are not invoked re-entrantly","Guard the stop call behind a flag or call timer(name) and inspect info.count first","Reset profiling state between runs so stale timers are cleared"],"exampleFix":"// before\nstop('myTimer'); // called in two branches but started once\n// after\nconst info = timer('myTimer');\nif (info.count > 0) stop('myTimer');","handlingStrategy":"validation","validationCode":"const info = timer('myTimer');\nif (info.count === 0) throw new Error('Timer never started');","typeGuard":"function isStarted(name: string): boolean {\n  const t = (<any>global).__nsTimers?.[name];\n  return !!t && t.count > 0;\n}","tryCatchPattern":"try {\n  stop('myTimer');\n} catch (e) {\n  if (!/paused more times than started/.test(e.message)) throw e;\n  // treat as already-stopped\n}","preventionTips":["Pair start/stop in try/finally so both always execute","Never stop a timer more than once per start","Reset profiling state between test runs"],"tags":["profiling","timers","state"],"backgroundTag":"unbalanced-timer-start-stop","analyzedSha":"6800aefa6511d23ddad8beb38ccc8541c5e91628","analyzedAt":"2026-08-30T20:04:56.809Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}