Skip to content

fix(logging): keep log records when the project root is on another mount - #1260

Merged
harry0703 merged 1 commit into
harry0703:mainfrom
SandroHub013:fix/log-path-cross-drive
Aug 25, 2026
Merged

fix(logging): keep log records when the project root is on another mount#1260
harry0703 merged 1 commit into
harry0703:mainfrom
SandroHub013:fix/log-path-cross-drive

Conversation

@SandroHub013

Copy link
Copy Markdown
Contributor

format_log_record shortens the absolute source path of every record into a project-relative ./... form. Two edge cases in that conversion are only reachable on Windows, and one of them silently kills logging.

The dropped records

os.path.relpath raises ValueError when the two paths sit on different Windows mounts. That is exactly what happens when the project is launched through a mapped network drive (net use Z: \\nas\share) or a subst drive: the call frame keeps the drive the user launched from, while PROJECT_ROOT is built with os.path.realpath, which resolves the mapping away.

Reproduced with subst X: <parent of the repo>, then importing the app from X:\MoneyPrinterTurbo:

--- Logging error in Loguru Handler #2 ---
Record was: {... 'file': (name='config.py', path='X:\\MoneyPrinterTurbo\\app\\config\\config.py'), ...}
Traceback (most recent call last):
  File ".venv\Lib\site-packages\loguru\_handler.py", line 137, in emit
    dynamic_format = self._formatter(record)
  File "X:\MoneyPrinterTurbo\app\utils\logging_utils.py", line 33, in format_log_record
    relative_path = os.path.relpath(file_path, PROJECT_ROOT)
ValueError: path is on mount 'X:', start on mount 'C:'
--- End of logging error ---

Loguru catches the formatter exception and discards the record, so the sink receives nothing at all. The terminal prints that dump instead of the log line, and since webui_task.py installs a second sink with the same formatter to feed the WebUI log panel, the generation log panel stays empty for the whole run.

The mixed separators

On Windows os.path.relpath returns backslash-separated segments, so the ./ prefix produces "./app\services\task.py". test_worker_logs_are_available_without_streamlit_session_state already pins the POSIX form:

r'"\./test/services/test_webui_task\.py:\d+": logged_start '

and fails on Windows today. That file is not in the windows-smoke job, which is why the drift was never caught.

The change

File Change
app/utils/logging_utils.py extract _project_relative_path: guard the ValueError, keep the absolute path for files outside the project root, normalise separators to /
test/services/test_webui_task.py three regression tests, next to the existing logging_utils coverage
.github/workflows/ci.yml add test/services/test_webui_task.py to the Windows smoke job

Files outside PROJECT_ROOT keep their absolute path as well: ./..\..\..\AppData\Local\... is no easier to read than the path it replaces.

Why the CI file is touched

The formatter change is only observable on Windows, and the test that proves it lives in a file the Windows job does not run. That one line is what keeps the same drift from coming back. Happy to drop it if you would rather keep the smoke list at core services only.

Verification

Full suite on Windows 11, Python 3.12, uv sync --frozen:

$ python -X utf8 -m pytest -q test    # before
4 failed, 740 passed, 11 skipped, 6951 subtests passed

$ python -X utf8 -m pytest -q test    # after
1 failed, 746 passed, 11 skipped, 6951 subtests passed

ruff check app cli.py main.py webui test and compileall app cli.py main.py webui test are both clean.

Each new test was confirmed to fail without the logging_utils.py change. Two of the three fail on Linux as well; test_log_paths_stay_posix_style_on_every_platform is a Windows-only guard, which is what the CI line is for.

The remaining failure is unrelated and fails identically on a clean main: test_headless_open_folder_shows_host_mapped_path sets sys.platform to "linux" in its fixture, which makes NumPy take its Linux branch on first import and call os.uname(), absent on Windows. It passes on the Linux matrix. Two further failures in the "before" run (test_corrupted_cache_is_removed_without_breaking_search, test_elevenlabs_connection_button_reports_success) are timing-dependent; both pass in isolation and passed in the "after" run.

os.path.relpath raises ValueError on Windows when the record's file and
PROJECT_ROOT resolve to different mounts. That happens whenever the project is
launched through a mapped network drive or a subst drive: the call frame keeps
X:\MoneyPrinterTurbo\..., while realpath resolves PROJECT_ROOT back to C:\...
Loguru catches the formatter error and discards the record, so the terminal and
the WebUI log panel both go silent. Fall back to the absolute path there, and
also when the file sits outside the project root, where "./" glued onto a ".."
climb is no easier to read than the original path.

Render the relative path with forward slashes as well, so Windows logs show
"./app/services/task.py" like every other platform instead of the mixed
"./app\services\task.py". test_webui_task.py already asserted the POSIX form
but is not part of the Windows smoke job, so the drift went unnoticed; add it
to that job to keep the regression covered on the platform where it appears.
@harry0703
harry0703 merged commit 6951758 into harry0703:main Aug 25, 2026
3 checks passed
@harry0703

Copy link
Copy Markdown
Owner

Thanks for the detailed report, Windows reproduction, and regression coverage. The fix looks good and has been merged. I also verified it against the latest main with the full test suite. Thanks again!

guo6x pushed a commit to guo6x/MoneyPrinterTurbo that referenced this pull request Aug 25, 2026
…unt (harry0703#1260)

os.path.relpath raises ValueError on Windows when the record's file and
PROJECT_ROOT resolve to different mounts. That happens whenever the project is
launched through a mapped network drive or a subst drive: the call frame keeps
X:\MoneyPrinterTurbo\..., while realpath resolves PROJECT_ROOT back to C:\...
Loguru catches the formatter error and discards the record, so the terminal and
the WebUI log panel both go silent. Fall back to the absolute path there, and
also when the file sits outside the project root, where "./" glued onto a ".."
climb is no easier to read than the original path.

Render the relative path with forward slashes as well, so Windows logs show
"./app/services/task.py" like every other platform instead of the mixed
"./app\services\task.py". test_webui_task.py already asserted the POSIX form
but is not part of the Windows smoke job, so the drift went unnoticed; add it
to that job to keep the regression covered on the platform where it appears.

(cherry picked from commit 6951758)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants