Local -OutputPath is broken on Linux: hardcoded backslash makes checkpoint paths unopenable
Nobody has claimed this yet.
- Dominant language
- PowerShell
- Stars
- 26
- Forks
- 7
- PR merge metrics
- No merged PRs in 30d
Description
Local -OutputPath is broken on Linux: hardcoded '\' separator makes checkpoint paths unopenable
Repo: microsoft/PAX
Version: v1.11.15
Summary
When -OutputPath is a local path, PAX normalises it to directory form by appending a hardcoded backslash:
PAX_Purview_Audit_Log_Processor_v1.11.15.ps1, lines 7240 and 7255:
if (-not $OutputPath.EndsWith('\') -and -not $OutputPath.EndsWith('/')) {
$OutputPath = $OutputPath + '\'
}
On Linux, \ is a legal filename character, not a separator. Passing -OutputPath /tmp/pax-output therefore yields /tmp/pax-output\, and every derived path is built underneath a directory that doesn't exist:
G-9: Failed to acquire checkpoint lock at /tmp/pax-output\/.pax_checkpoint_20260826_103115.json.lock:
Exception calling "Open" with "4" argument(s): "Could not find a part of the path
'/tmp/pax-output\/.pax_checkpoint_20260826_103115.json.lock'." Another process may have raced in.
The run aborts before any data is fetched.
Why the error is misleading
It is reported as a checkpoint lock contention problem — "Another process may have raced in" — which sends you looking for a stale lock or a concurrent run. The actual fault is the path separator, and the backslash is easy to miss inside a long path string.
Why it isn't caught by the shipped container guidance
fabric_resources/ documents running PAX in an Azure Container Apps Job, i.e. on Linux — but always with -OutputPath pointing at a SharePoint or OneLake URL. That takes the remote-output branch, which builds the scratch directory correctly:
line 7447-7448:
$sep = [System.IO.Path]::DirectorySeparatorChar
if (-not $OutputPath.EndsWith($sep)) { $OutputPath = $OutputPath + $sep }
So the bug only bites when a Linux host stages output locally — e.g. exporting to a local directory and then uploading, or writing to a mounted volume. Both are reasonable containerised patterns.
Reproduction
Linux container (mcr.microsoft.com/powershell:lts-7.4-ubuntu-22.04, the base used by fabric_resources/Dockerfile/PAX.Dockerfile):
pwsh -File PAX_Purview_Audit_Log_Processor_v1.11.15.ps1 \
-Rollup -IncludeUserInfo -Auth AppRegistration \
-TenantId <t> -ClientId <c> -ClientSecret <s> \
-StartDate 2026-08-23 -EndDate 2026-08-27 \
-OutputPath /tmp/pax-output \
-OutputPathUserInfo /tmp/pax-output \
-OutputPathLog /tmp/pax-output
Fails immediately with the G-9 error above.
Workaround
Pass a trailing separator on every -OutputPath*, since the append is skipped when one is already present:
-OutputPath /tmp/pax-output/
With that single change the same command runs to completion (62 partitions, rollup CSVs written).
Suggested fix
Use [System.IO.Path]::DirectorySeparatorChar at lines 7240 and 7255, matching what line 7448 already does. Optionally also accept / as a separator on Windows, which .NET handles natively.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Inspect PAX_Purview_Audit_Log_Processor_v1.11.15.ps1 at lines 7240 and 7255, then compare the separator handling with lines 7447-7448. Reproduce the command using a local Linux path without a trailing separator and verify that checkpoint and output paths open successfully. Done means local OutputPath, OutputPathUserInfo, and OutputPathLog work without the workaround while remote output behavior remains intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- powershell
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100