You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
FunctionLoader.SetupWellKnownPaths enumerates the function app root directory with a filtered Directory.EnumerateFiles(..., "profile.ps1", ...) call and no existence check or fallback. On the PowerShell 7.6 worker (.NET 10), this enumeration can throw a hard, terminating failure of the worker for apps that do not have a profile.ps1, even though the content share (C:\home\site\wwwroot) is mounted and readable. This issue tracks making the worker resilient to that failure; #1147 covers the underlying .NET runtime root cause.
Observed failure
Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException : Result: Failure
Exception: Could not find file 'C:\home\site\wwwroot'.
Stack: at System.IO.Enumeration.FileSystemEnumerator`1.FindNextEntry()
at System.IO.Enumeration.FileSystemEnumerator`1.MoveNext()
at System.Linq.Enumerable.TryGetFirstNonIterator[TSource](IEnumerable`1 source, Boolean& found)
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at Microsoft.Azure.Functions.PowerShellWorker.FunctionLoader.SetupWellKnownPaths(FunctionLoadRequest request, String managedDependenciesPath)
at Microsoft.Azure.Functions.PowerShellWorker.RequestProcessor.SetupAppRootPathAndModulePath(FunctionLoadRequest functionLoadRequest, String managedDependenciesPath)
at Microsoft.Azure.Functions.PowerShellWorker.RequestProcessor.ProcessFunctionLoadRequest(StreamingMessage request)
Relevant code
src/FunctionLoader.cs:
// Resolve the FunctionApp profile pathvaroptions=newEnumerationOptions{MatchCasing=MatchCasing.CaseInsensitive};varprofiles=Directory.EnumerateFiles(FunctionAppRootPath,"profile.ps1",options);FunctionAppProfilePath=profiles.FirstOrDefault();
Directory.EnumerateFiles is lazy, so the directory is walked when FirstOrDefault() pulls the first entry — which is exactly where the stack trace lands. The resolved path in the error is the correct, fully-qualified C:\home\site\wwwroot, so this is not a path-computation bug — the worker computed the right directory and then failed while enumerating it.
Impact
ProcessFunctionLoadRequest caches the exception into _initTerminatingError, so a single failure here is treated as terminating: every subsequent FunctionLoadRequest returns the same failure until the worker is recycled.
Proposed enhancement
Make SetupWellKnownPaths resilient so a profile.ps1 lookup can never take down the worker:
Resolve profile.ps1 without a filtered enumeration. Replace the filtered Directory.EnumerateFiles(FunctionAppRootPath, "profile.ps1", ...) + FirstOrDefault() with a direct existence check on the known filename, e.g.:
The filename is fixed and known, so there is no need to enumerate the directory with an OS-level filter at all. File.Exists does not go through the filtered FileSystemEnumerator code path and returns false (rather than throwing) when the file is absent — which is exactly the "no profile.ps1" case that triggers the failure on the affected .NET versions (see SetupWellKnownPaths wwwroot enumeration fails only on PowerShell 7.6 (.NET 10) worker — Directory.EnumerateFiles regression in .NET 10.0.9, fixed in 10.0.11 #1147). On Windows the file system is case-insensitive, so this preserves the existing case-insensitive lookup behavior; if strict cross-platform case-insensitive matching is required, guard a single-directory enumeration behind a Directory.Exists check and a try/catch.
Do not cache a wwwroot enumeration/existence error as terminating. Avoid storing this class of failure in _initTerminatingError so a spurious failure does not require a full worker recycle to recover.
(Optional) Guard the root itself. Add a Directory.Exists(FunctionAppRootPath) check so any future filesystem-visibility issue produces a clear, non-terminating diagnostic rather than an opaque enumeration exception.
Note: item (1) is the key change — it makes the worker functional for apps without a profile.ps1 even while running on an affected .NET 10 runtime (10.0.9 / 10.0.10), independent of the platform runtime update tracked in #1147. This gives us a worker-side fix we can ship without waiting on the platform.
Summary
FunctionLoader.SetupWellKnownPathsenumerates the function app root directory with a filteredDirectory.EnumerateFiles(..., "profile.ps1", ...)call and no existence check or fallback. On the PowerShell 7.6 worker (.NET 10), this enumeration can throw a hard, terminating failure of the worker for apps that do not have aprofile.ps1, even though the content share (C:\home\site\wwwroot) is mounted and readable. This issue tracks making the worker resilient to that failure; #1147 covers the underlying .NET runtime root cause.Observed failure
Relevant code
src/FunctionLoader.cs:Directory.EnumerateFilesis lazy, so the directory is walked whenFirstOrDefault()pulls the first entry — which is exactly where the stack trace lands. The resolved path in the error is the correct, fully-qualifiedC:\home\site\wwwroot, so this is not a path-computation bug — the worker computed the right directory and then failed while enumerating it.Impact
ProcessFunctionLoadRequestcaches the exception into_initTerminatingError, so a single failure here is treated as terminating: every subsequentFunctionLoadRequestreturns the same failure until the worker is recycled.Proposed enhancement
Make
SetupWellKnownPathsresilient so aprofile.ps1lookup can never take down the worker:Resolve
profile.ps1without a filtered enumeration. Replace the filteredDirectory.EnumerateFiles(FunctionAppRootPath, "profile.ps1", ...)+FirstOrDefault()with a direct existence check on the known filename, e.g.:The filename is fixed and known, so there is no need to enumerate the directory with an OS-level filter at all.
File.Existsdoes not go through the filteredFileSystemEnumeratorcode path and returnsfalse(rather than throwing) when the file is absent — which is exactly the "noprofile.ps1" case that triggers the failure on the affected .NET versions (see SetupWellKnownPaths wwwroot enumeration fails only on PowerShell 7.6 (.NET 10) worker — Directory.EnumerateFiles regression in .NET 10.0.9, fixed in 10.0.11 #1147). On Windows the file system is case-insensitive, so this preserves the existing case-insensitive lookup behavior; if strict cross-platform case-insensitive matching is required, guard a single-directory enumeration behind aDirectory.Existscheck and atry/catch.Do not cache a wwwroot enumeration/existence error as terminating. Avoid storing this class of failure in
_initTerminatingErrorso a spurious failure does not require a full worker recycle to recover.(Optional) Guard the root itself. Add a
Directory.Exists(FunctionAppRootPath)check so any future filesystem-visibility issue produces a clear, non-terminating diagnostic rather than an opaque enumeration exception.Note: item (1) is the key change — it makes the worker functional for apps without a
profile.ps1even while running on an affected .NET 10 runtime (10.0.9 / 10.0.10), independent of the platform runtime update tracked in #1147. This gives us a worker-side fix we can ship without waiting on the platform.Related
Directory.EnumerateFilesbehavior change (regression in 10.0.9, fixed in 10.0.11) and the platform runtime update.Environment
wwwrootdoes not contain aprofile.ps1