my_backup — Mystery Folders Investigation & Fix
Section titled “my_backup — Mystery Folders Investigation & Fix”Project: D:\FSS\Software\Utils\PythonUtils\my_backup
What Happened
Section titled “What Happened”Three mystery directories appeared in the my_backup project root after the monthly WSL cron run on 2026-05-01 05:00:
D:(with nested contents)\\NAS-TLS\bak\Kopia_Active(single directory with backslash name)\\NAS-TLS\bak\Kopia_Static(single directory with backslash name)
Trigger: Monthly maintenance cron job (0 5 1 * * ... my_backup --maintenance full) runs the full pipeline under WSL, including Windows-only steps that misbehave with Linux path semantics.
Root Causes
Section titled “Root Causes”Bug 1: Windows absolute log path in config.yaml
Section titled “Bug 1: Windows absolute log path in config.yaml”config.yaml had log_file: "D:/FSS/Software/Utils/PythonUtils/my_backup/logs/backup.log". setup_logging() in utils.py called os.makedirs(log_dir) on this path. On Linux, D:/... is not absolute (Path.is_absolute() returns False), so Python created the full relative path D:/FSS/.../logs/ in the project root CWD.
Cascade: after D:/FSS/ existed, initialization() also copied .kopiaignore to D:/FSS/.kopiaignore.
The D: directory contained:
D:/FSS/.kopiaignoreD:/FSS/Software/Utils/PythonUtils/my_backup/logs/backup.log
Bug 2: UNC mirror paths passed to os.makedirs on Linux
Section titled “Bug 2: UNC mirror paths passed to os.makedirs on Linux”mirrors() skips drive-letter validation for UNC paths (\\-prefixed) and calls os.makedirs(dest) if dest doesn’t exist. On Linux, \ is not a path separator — the entire UNC string \\NAS-TLS\bak\Kopia_Active is treated as a single directory name and created in the CWD.
Fixes Applied
Section titled “Fixes Applied”| Fix | File | Change |
|---|---|---|
| 1 | config.yaml | log_file → "logs/backup.log" (relative) |
| 2 | utils.py setup_logging() | Resolve relative paths against PROJECT_ROOT using Path.is_absolute() |
| 3 | tasks.py initialization() | if os.name != 'nt': return |
| 4 | tasks.py mirrors() | if os.name != 'nt': continue after rclone branch |
| 5 | tasks.py seven_zip_backups() | if os.name != 'nt': return |
Committed to my_backup: a704c6c
- 7z password exposed via
-p{password}in process args (visible inps) — noted, not fixed (out of scope per DO NO HARM) - LESSONS.md updated with two new cross-platform path handling entries
check_backups.pyhad a pre-existing uncommitted addition (orphan snapshot detection) — included in the same commit