OpenBB-finance/OpenBB · warning · RuntimeError
Another build process is running and has locked {self._lock_
Error message
Another build process is running and has locked {self._lock_path} What it means
PackageBuilder._run raises this RuntimeError when acquiring its exclusive file lock raises BlockingIOError, meaning another openbb-build process already holds the lock at self._lock_path. The lock serializes static-asset builds so two concurrent builds cannot corrupt the generated package tree.
Source
Thrown at openbb_platform/core/openbb_core/app/static/package_builder.py:224
if self.lint:
self._run_linters()
except BaseException as e:
if not isinstance(e, (KeyboardInterrupt, SystemExit)):
self.console.error("\nBuild failed!") # type: ignore # pylint: disable=E1101
self.console.error(f"Error: {e}") # type: ignore # pylint: disable=E1101
self.console.error(traceback.format_exc()) # type: ignore # pylint: disable=E1101
self.console.error("\nInstruction:") # type: ignore # pylint: disable=E1101
self.console.error( # type: ignore # pylint: disable=E1101
"Set OPENBB_DEBUG_MODE='true' environment variable and run "
"'openbb-build' again to see verbose output."
)
self._clean(modules)
raise
finally:
if hasattr(signal, "SIGTERM"):
signal.signal(signal.SIGTERM, original_sigterm)
except BlockingIOError:
raise RuntimeError( # noqa # pylint: disable=W0707
f"Another build process is running and has locked {self._lock_path}"
)
finally:
# Release the file lock, suppressing any exceptions during cleanup
with contextlib.suppress(Exception):
file_lock.release()
def _clean(self, modules: str | list[str] | None = None) -> None:
"""Delete the assets and package folder or modules before building."""
shutil.rmtree(self.directory / "assets", ignore_errors=True)
if modules:
for module in modules:
module_path = self.directory / "package" / f"{module}.py"
if module_path.exists():
module_path.unlink()
else:
shutil.rmtree(self.directory / "package", ignore_errors=True)
View on GitHub (pinned to 3e071fcc2c)
Solutions
- Wait for the running build to finish, then re-run openbb-build
- Find and stop the other process: ps aux | grep openbb-build / lsof <lock_path>, then kill it
- If no other process exists (stale holder died), remove the stale lock file and retry
- In CI, serialize build steps so only one job builds at a time
Defensive patterns
Strategy: retry
Validate before calling
import os
LOCK = os.path.expanduser('~/.openbb_platform/lock')
def lock_free(path: str = LOCK) -> bool:
try:
f = open(path, 'a+')
import fcntl
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
fcntl.flock(f, fcntl.LOCK_UN)
f.close()
return True
except (BlockingIOError, OSError):
return False Try / catch
import time
for attempt in range(3):
try:
from openbb import obb # may trigger build
break
except RuntimeError as e:
if 'locked' not in str(e):
raise
time.sleep(30 * (attempt + 1)) # wait for the other build
else:
raise RuntimeError('openbb build stayed locked') Prevention
- Never run two openbb-build processes in the same environment simultaneously
- Serialize build steps in CI (single job or explicit dependencies)
- Kill leftover build processes before rebuilding: lsof + kill
When it happens
Trigger: Running 'openbb-build' (or openbb.build()) twice concurrently: a previous build still running in another terminal, a build left behind by an IDE task, or a stale lock file held by a zombie process. Also happens when a build is triggered on import while another interpreter session is mid-build.
Common situations: Two terminal windows both running openbb-build; CI jobs sharing a container workspace hitting the same lock file; a crashed build whose process still holds the flock; Docker builds where a long build in one layer overlaps the next.
Related errors
- Failed to build the OpenBB platform static assets. {e} -> {
- Unsupported file format. Please use .json or .env files.
- Failed to get Jupyter URL
- Invalid extension type(s): {', '.join(invalid)}. Valid choic
- At least one extension type must be selected.
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/9a884a0a1759b300.
Report an issue: GitHub.