Bug Description
When LANGFLOW_DATABASE_URL is set to a relative SQLite path (e.g. sqlite:///db/langflow.db) and langflow run is startedfrom a directory other than the project root, two bugs fire in sequence:
- SQLAlchemy resolves the relative path against the shell's CWD, not the project root, so it tries to open/create a DBat the wrong location and fails.
- Because startup fails before the bundle-loading step, temp_dirs is never assigned in lifespan(), so the shutdown cleanup crashes with UnboundLocalError: cannot access local variable 'temp_dirs' where it is not associated with a value.
The second crash masks the real error — the user sees two chained exceptions and has to trace back to understand that the actual cause was a path resolution issue.
Reproduction
.env in project root:
LANGFLOW_DATABASE_URL=sqlite:///db/langflow.db
cd /some/other/directory
langflow run --env-file /path/to/.env
Observed Behaviour
RuntimeError: Error creating DB and tables
During handling of the above exception, another exception occurred:
UnboundLocalError: cannot access local variable 'temp_dirs' where it is not
associated with a value
Full traceback (condensed):
langflow/main.py:198 await initialize_services(fix_migration=fix_migration)
langflow/services/utils.py:602 await initialize_database(fix_migration=fix_migration)
langflow/services/database/utils.py:34 raise RuntimeError(msg) from exc
RuntimeError: Error creating DB and tables
During handling of the above exception, another exception occurred:
langflow/main.py:588
temp_dir_cleanups = [asyncio.to_thread(temp_dir.cleanup) for temp_dir in temp_dirs]
UnboundLocalError: cannot access local variable 'temp_dirs' where it is not associated with a value
Expected behavior
- A relative SQLite path should be resolved to absolute at service initialisation time (anchored to CWD at startup), making behaviour consistent regardless of which directory langflow run is invoked from.
- temp_dirs should be initialised to [] before the try block in lifespan() so cleanup never crashes on early startup failures.
Root Cause
services/database/service.py — _sanitize_database_url
The method normalises the driver name (sqlite → sqlite+aiosqlite) but does not touch the path component. SQLAlchemy receives the relative path and resolves it against the process CWD, which may not be the project root.
main.py — lifespan
temp_dirs is only assigned inside the bundle-loading branch (lines ~276–281), which runs after initialize_services. When
During handling of the above exception, another exception occurred:
UnboundLocalError: cannot access local variable 'temp_dirs' where it is not
associated with a value
Full traceback (condensed):
langflow/main.py:198 await initialize_services(fix_migration=fix_migration)
langflow/services/utils.py:602 await initialize_database(fix_migration=fix_migration)
langflow/services/database/utils.py:34 raise RuntimeError(msg) from exc
RuntimeError: Error creating DB and tables
During handling of the above exception, another exception occurred:
langflow/main.py:588
temp_dir_cleanups = [asyncio.to_thread(temp_dir.cleanup) for temp_dir in temp_dirs]
UnboundLocalError: cannot access local variable 'temp_dirs' where it is not associated with a value
Expected Behaviour
- A relative SQLite path should be resolved to absolute at service initialisation time (anchored to CWD at startup),
making behaviour consistent regardless of which directory langflow run is invoked from.
- temp_dirs should be initialised to [] before the try block in lifespan() so cleanup never crashes on early startup
failures.
Root Cause
services/database/service.py — _sanitize_database_url
The method normalises the driver name (sqlite → sqlite+aiosqlite) but does not touch the path component. SQLAlchemy
receives the relative path and resolves it against the process CWD, which may not be the project root.
main.py — lifespan
temp_dirs is only assigned inside the bundle-loading branch (lines ~276–281), which runs after initialize_services. When
initialize_services raises, execution jumps to the finally block, which tries to iterate temp_dirs before it was ever
set.
Proposed Fix
_sanitize_database_url in service.py:
if driver in {"sqlite", "sqlite+aiosqlite"}:
driver = "sqlite+aiosqlite"
raw_path = url_components[1][1:] # strip the separator slash
db_path = Path(raw_path)
if not db_path.is_absolute():
db_path = Path.cwd() / db_path
self.database_url = f"{driver}:///{db_path.as_posix()}"
lifespan in main.py:
sync_flows_from_fs_task = None
mcp_init_task = None
models_dev_refresh_task = None
temp_dirs = [] # ← initialise before try so cleanup never crashes
try:
...
- .venv\Lib\site-packages\langflow\services\database\service.py — _sanitize_database_url: resolves relative SQLite
paths to absolute using CWD at startup.
- .venv\Lib\site-packages\langflow\main.py — lifespan: initialises temp_dirs = [] before the try block.
service.py
Environment
- Langflow: 1.10.0
- OS: Windows 11
- Python: 3.13.7
- Database: SQLite
Who can help?
main.py
Operating System
Windows 11
Langflow Version
1.10.0
Python Version
3.12
Screenshot
service.py
Flow File
No response
Bug Description
When LANGFLOW_DATABASE_URL is set to a relative SQLite path (e.g. sqlite:///db/langflow.db) and langflow run is startedfrom a directory other than the project root, two bugs fire in sequence:
The second crash masks the real error — the user sees two chained exceptions and has to trace back to understand that the actual cause was a path resolution issue.
Reproduction
.env in project root:
LANGFLOW_DATABASE_URL=sqlite:///db/langflow.db
cd /some/other/directory
langflow run --env-file /path/to/.env
Observed Behaviour
RuntimeError: Error creating DB and tables
During handling of the above exception, another exception occurred:
UnboundLocalError: cannot access local variable 'temp_dirs' where it is not
associated with a value
Full traceback (condensed):
langflow/main.py:198 await initialize_services(fix_migration=fix_migration)
langflow/services/utils.py:602 await initialize_database(fix_migration=fix_migration)
langflow/services/database/utils.py:34 raise RuntimeError(msg) from exc
RuntimeError: Error creating DB and tables
During handling of the above exception, another exception occurred:
langflow/main.py:588
temp_dir_cleanups = [asyncio.to_thread(temp_dir.cleanup) for temp_dir in temp_dirs]
UnboundLocalError: cannot access local variable 'temp_dirs' where it is not associated with a value
Expected behavior
Root Cause
services/database/service.py — _sanitize_database_url
The method normalises the driver name (sqlite → sqlite+aiosqlite) but does not touch the path component. SQLAlchemy receives the relative path and resolves it against the process CWD, which may not be the project root.
main.py — lifespan
temp_dirs is only assigned inside the bundle-loading branch (lines ~276–281), which runs after initialize_services. When
During handling of the above exception, another exception occurred:
UnboundLocalError: cannot access local variable 'temp_dirs' where it is not
associated with a value
Full traceback (condensed):
langflow/main.py:198 await initialize_services(fix_migration=fix_migration)
langflow/services/utils.py:602 await initialize_database(fix_migration=fix_migration)
langflow/services/database/utils.py:34 raise RuntimeError(msg) from exc
RuntimeError: Error creating DB and tables
During handling of the above exception, another exception occurred:
langflow/main.py:588
temp_dir_cleanups = [asyncio.to_thread(temp_dir.cleanup) for temp_dir in temp_dirs]
UnboundLocalError: cannot access local variable 'temp_dirs' where it is not associated with a value
Expected Behaviour
making behaviour consistent regardless of which directory langflow run is invoked from.
failures.
Root Cause
services/database/service.py — _sanitize_database_url
The method normalises the driver name (sqlite → sqlite+aiosqlite) but does not touch the path component. SQLAlchemy
receives the relative path and resolves it against the process CWD, which may not be the project root.
main.py — lifespan
temp_dirs is only assigned inside the bundle-loading branch (lines ~276–281), which runs after initialize_services. When
initialize_services raises, execution jumps to the finally block, which tries to iterate temp_dirs before it was ever
set.
Proposed Fix
_sanitize_database_url in service.py:
if driver in {"sqlite", "sqlite+aiosqlite"}:
driver = "sqlite+aiosqlite"
raw_path = url_components[1][1:] # strip the separator slash
db_path = Path(raw_path)
if not db_path.is_absolute():
db_path = Path.cwd() / db_path
self.database_url = f"{driver}:///{db_path.as_posix()}"
lifespan in main.py:
sync_flows_from_fs_task = None
mcp_init_task = None
models_dev_refresh_task = None
temp_dirs = [] # ← initialise before try so cleanup never crashes
try:
...
paths to absolute using CWD at startup.
service.py
Environment
Who can help?
main.py
Operating System
Windows 11
Langflow Version
1.10.0
Python Version
3.12
Screenshot
service.py
Flow File
No response