Reject whitespace-only item and property values when consumed as paths
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 141
Description
## Summary
Reject path inputs whose entire value consists only of whitespace (`string.IsNullOrWhiteSpace(value)` is `true`). Apply this consistently on Windows, Linux, and macOS.
## Motivation
Supporting path names that consist only of whitespace does not provide a meaningful MSBuild scenario, but preserving that behavior creates compatibility and correctness risks for path absolutization.
Windows path APIs may reject or normalize whitespace-only values, while Unix can preserve them as legal path segments. This platform difference complicates path handling and makes multithreaded task migrations easier to get wrong. A whitespace-only property, item identity, or metadata value can also be unintentionally resolved relative to the project directory and then have its whitespace trimmed instead of being reported as invalid input.
## Proposed implementation
### Central validation in `AbsolutePath`
Add a wave-gated `string.IsNullOrWhiteSpace(path)` check in the `AbsolutePath` constructor. Add a localized Framework exception message and throw `ArgumentException`.
The constructor receives only the path value and base path. It does not receive the originating task parameter, item, property, or metadata name, so its exception is the generic fallback when no higher-level caller supplies that context.
### Contextual diagnostics at built-in task call sites
When a built-in task calls `TaskEnvironment.GetAbsolutePath`, the task code knows which of its inputs it is processing. For example, at a call such as `TaskEnvironment.GetAbsolutePath(SourceFiles[i].ItemSpec)`, the task can validate the value before the call and log an error containing `nameof(SourceFiles)`, the item value, and the item index.
This contextual diagnostic is possible, but it requires updating each relevant task call site. The existing `TaskEnvironment.GetAbsolutePath(string)` API receives only the path string and cannot infer the task property or item name automatically.
### Contextual diagnostics for typed path parameters
PR #13971 implements typed task parameters and items. When a task author changes an input type from `string` or `ITaskItem` to `AbsolutePath`, `FileInfo`, or `DirectoryInfo`, parameter binding routes the value through `TaskExecutionHost`.
`TaskExecutionHost` calls `TaskEnvironment.GetAbsolutePath`, the central `AbsolutePath` validation throws `ArgumentException` for whitespace-only values, and the existing parameter-binding error handling converts that exception into a user-friendly error containing the value, task parameter name, declared type, task name, and project location.
Legacy tasks that call `TaskEnvironment.GetAbsolutePath` but do not add task-level validation receive the generic `AbsolutePath` fallback error. Tasks that neither use typed path parameters nor resolve their values through `TaskEnvironment.GetAbsolutePath` cannot be identified generically as path consumers and will retain their existing behavior.
## Change Wave
Gate behavior changes to existing path consumers with `ChangeWaves.Wave18_10`. Setting `MSBUILDDISABLEFEATURESFROMVERSION=18.10` preserves the previous behavior until the wave rotates out.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.