jax-ml/jax · error · RuntimeError
Profile has already been started. Only one profile may be ru
Error message
Profile has already been started. Only one profile may be run at a time.
What it means
jax.profiler.start_trace raises RuntimeError if a profiling session is already active — only one trace may run at a time per process, enforced via `_profile_state.profile_session`.
Source
Thrown at jax/_src/profiler.py:185
Only one trace may be collected at a time. A RuntimeError will be raised if
:func:`start_trace` is called while another trace is running.
Args:
log_dir: The directory to save the profiler trace to (usually the
TensorBoard log directory).
create_perfetto_link: A boolean which, if true, creates and prints link to
the Perfetto trace viewer UI (https://ui.perfetto.dev). The program will
block until the link is opened and Perfetto loads the trace.
create_perfetto_trace: A boolean which, if true, additionally dumps a
``perfetto_trace.json.gz`` file that is compatible for upload with the
Perfetto trace viewer UI (https://ui.perfetto.dev). The file will also be
generated if ``create_perfetto_link`` is true. This could be useful if you
want to generate a Perfetto-compatible trace without blocking the process.
profiler_options: Profiler options to configure the profiler for collection.
"""
with _profile_state.lock:
if _profile_state.profile_session is not None:
raise RuntimeError("Profile has already been started. "
"Only one profile may be run at a time.")
clear_metadata()
# Make sure backends are initialized before creating a profiler
# session. Otherwise on Cloud TPU, libtpu may not be initialized before
# creating the tracer, which will cause the TPU tracer initialization to
# fail and no TPU operations will be included in the profile.
xla_bridge.get_backend()
options = profiler_options
if options is None:
options = ProfileOptions()
set_metadata("jax_version", jax_version_module.__version__)
jaxlib_version_str = ".".join(map(str, version_lib))
set_metadata("jaxlib_version", jaxlib_version_str)
for backend_name in xla_bridge.backends():
try:
backend = xla_bridge.get_backend(backend_name)
set_metadata(f"{backend.platform}_version", backend.platform_version)View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Always pair start_trace with stop_trace (prefer the `jax.profiler.trace()` context manager)
- Call stop_trace before starting a new trace
- Add locking/flags around programmatic profiling in multi-threaded code
Example fix
# before
jax.profiler.start_trace('/tmp/t1')
jax.profiler.start_trace('/tmp/t2') # RuntimeError
# after
with jax.profiler.trace('/tmp/t1'):
run_model() Defensive patterns
Strategy: try-catch
Try / catch
try:
jax.profiler.start_trace(log_dir)
except RuntimeError as e:
if 'already been started' in str(e):
jax.profiler.stop_trace()
jax.profiler.start_trace(log_dir)
else:
raise Prevention
- Prefer `with jax.profiler.trace(...):` context manager
- Never start traces from multiple threads without a lock
When it happens
Trigger: Nested or overlapping `start_trace` calls: calling start_trace twice without stop_trace, or concurrent threads starting traces; the `trace` context manager used re-entrantly.
Common situations: Repeated notebook cells; concurrent profiling from multiple libraries; forgetting stop_trace after an exception bypassed the context manager.
Related errors
- Only one profiler server can be active at a time.
- Preemption sync manager should only be initialized once.
- No active profiler server.
- Invalid trace folder: {latest_trace_folder}
- No profile started
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/102f55efdd04b6a6.
Report an issue: GitHub.