Skip to content

feat: configurable root path for read-only environments#26

Open
edgett wants to merge 1 commit intomanagedcode:mainfrom
edgett:feature/configurable-root-path
Open

feat: configurable root path for read-only environments#26
edgett wants to merge 1 commit intomanagedcode:mainfrom
edgett:feature/configurable-root-path

Conversation

@edgett
Copy link

@edgett edgett commented Feb 6, 2026

Summary

  • MarkItDownPathResolver hardcodes .markitdown under Environment.CurrentDirectory, which is read-only in Azure Functions (and similar containerized/serverless environments), crashing on the first conversion.
  • Replaced the Lazy<string> in the resolver with a lock-guarded double-check init pattern and added a Configure(string) method so the root can be redirected before any conversion runs.
  • Added MarkItDownOptions.RootPath for non-DI callers and MarkItDownServiceBuilder.UseRootPath() for DI callers.

Usage

DI (Program.cs):

services.AddMarkItDown(builder =>
{
    builder.UseRootPath(Path.Combine(Path.GetTempPath(), ".markitdown"));
});

Non-DI:

var client = new MarkItDownClient(new MarkItDownOptions
{
    RootPath = Path.Combine(Path.GetTempPath(), ".markitdown")
});

Safety

  • Configure() and RootPath first-access share a single lock -- no race window between writing the config and materializing the root.
  • Conflicting paths throw InvalidOperationException instead of silently ignoring.
  • Paths are normalized via Path.GetFullPath() with platform-aware comparison (case-insensitive on Windows, ordinal on Linux).

Files changed

  • src/MarkItDown/Utilities/MarkItDownPathResolver.cs -- core fix (lock-guarded init + Configure)
  • src/MarkItDown/Core/MarkItDownOptions.cs -- added RootPath property
  • src/MarkItDown/Core/MarkItDownClient.cs -- 2 lines wiring RootPath in constructor
  • src/MarkItDown/DependencyInjection/MarkItDownServiceBuilder.cs -- added UseRootPath() method
  • AGENTS.md -- documented the configurability rule

Test plan

  • Full test suite passes (383 passed, 0 failed, 5 skipped manual/live)
  • Verify in Azure Function that setting RootPath to temp folder resolves the crash

Replace hardcoded Environment.CurrentDirectory root in MarkItDownPathResolver with a lock-guarded, configurable init so Azure Functions and other read-only hosts can redirect workspaces to a writable directory.

- MarkItDownPathResolver: lock-guarded double-check init with Configure(string) and platform-aware path comparison

- MarkItDownOptions.RootPath for non-DI callers

- MarkItDownServiceBuilder.UseRootPath() for DI callers

- Wired in MarkItDownClient constructor before any other init

Co-authored-by: Cursor <cursoragent@cursor.com>
@edgett
Copy link
Author

edgett commented Feb 7, 2026

I verfied:

  1. Setting the new RootPath configuration option to Path.Combine(Path.GetTempPath(), "markitdown", "workspaces"); on Azure Functions, running on a Linux App Service works.
  2. Setting the new RootPath configuration option to same as above works on Windows in development env.

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.

1 participant