jax-ml/jax · error · RuntimeError

No profile started

Error message

No profile started

What it means

jax.profiler.stop_trace raises RuntimeError when `_profile_state.profile_session` is None — i.e., no start_trace is active. This is the lifecycle guard matching start_trace's already-started check.

Source

Thrown at jax/_src/profiler.py:280

      print(f"Open URL in browser: {url}")

      # Once ui.perfetto.dev acquires trace.json from this server we can close
      # it down.
      while httpd.__dict__.get('last_request') != '/' + filename:
        httpd.handle_request()
  finally:
    os.chdir(orig_directory)

def stop_trace():
  """Stops the currently-running profiler trace.

  The trace will be saved to the ``log_dir`` passed to the corresponding
  :func:`start_trace` call. Raises a RuntimeError if a trace hasn't been started.
  """
  with _profile_state.lock:
    profile_session = _profile_state.profile_session
    if profile_session is None:
      raise RuntimeError("No profile started")
    profile_session.stop_and_export(str(_profile_state.log_dir))
    if _profile_state.create_perfetto_trace:
      abs_filename = _write_perfetto_trace_file(str(_profile_state.log_dir))
      if _profile_state.create_perfetto_link:
        _host_perfetto_trace_file(abs_filename)
    _profile_state.reset()
    clear_metadata()


def stop_and_get_fdo_profile() -> bytes | str:
  """Stops the currently-running profiler trace and export fdo_profile.

  Currently, this is only supported for GPU.
  Raises a RuntimeError if a trace hasn't been started.
  """
  with _profile_state.lock:
    profile_session = _profile_state.profile_session
    if profile_session is None:

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Only call stop_trace after a successful start_trace; track state with a flag
  2. Use the `jax.profiler.trace()` context manager which pairs start/stop automatically
  3. Wrap stop_trace in try/except RuntimeError for idempotent cleanup

Example fix

# before
jax.profiler.stop_trace()  # nothing started
# after
with jax.profiler.trace('/tmp/log'):
  run_model()
Defensive patterns

Strategy: try-catch

Try / catch

try:
    jax.profiler.stop_trace()
except RuntimeError as e:
    if 'No profile started' in str(e):
        pass
    else:
        raise

Prevention

When it happens

Trigger: Calling stop_trace before start_trace, after a previous stop_trace, or after an exception skipped start_trace while cleanup still ran.

Common situations: Cleanup/finally blocks calling stop_trace unconditionally; mispaired context managers; tests stopping traces started in a different process.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/88fd90288581e77c. Report an issue: GitHub.