---
coverage: Razor-layer (src/Razor) known issues, quirks & workarounds
---

# Razor — Known Issues

Layer-specific quirks for Razor tooling/compiler. Load when working under
`src/Razor`. Cross-cutting issues live in `.github/memory/KNOWN_ISSUES.md`.

## Build wrappers can mangle a semicolon-delimited `-projects` list

**Affected area:** `build.cmd` / PowerShell build wrappers
**Description:** Passing a semicolon-delimited project list through a nested
PowerShell invocation can make PowerShell treat `;` as a statement separator and
even open `.csproj` files in Visual Studio.
**Workaround:** Build a single project at a time, or invoke the underlying script
so the full `-projects` value is preserved as one argument.

## Shared projects need `.projitems` entries

**Affected area:** `Microsoft.CodeAnalysis.Razor.CohostingShared` (and its
`.UnitTests`) shared projects
**Description:** Files under
`src\Razor\src\Razor\src\Microsoft.CodeAnalysis.Razor.CohostingShared\` and
`src\Razor\src\Razor\test\Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests\`
are compiled through their `.projitems` files. Adding a new `.cs` file to the
shared tree is not enough on its own.
**Workaround:** Also add a matching `<Compile Include="...">` entry to
`Microsoft.CodeAnalysis.Razor.CohostingShared.projitems` or
`Microsoft.CodeAnalysis.Razor.CohostingShared.UnitTests.projitems`, or the file
won't be built/tested by the importing projects.

## Duplicate global analyzer config keys (`MultipleGlobalAnalyzerKeys`)

**Affected area:** Razor projects, which receive global configs from both
`eng/config/globalconfigs/*.globalconfig` and `src/Razor/*.globalconfig` overlays
**Description:** The same key in two global configs causes compiler error
`MultipleGlobalAnalyzerKeys`, and the key is left unset.
**Workaround:** Don't redefine a key already present in the base config.

## Empty tag pairs use missing name tokens

**Affected area:** Razor syntax consumers such as linked editing
**Description:** The parser represents `<></>` with start- and end-tag name
tokens that are both missing and have zero-width spans. The general
`SyntaxToken.IsValid()` helper rejects these tokens.
**Workaround:** Features that intentionally support editing an empty tag pair
must recognize both missing name tokens together and use their zero-width spans.
Do not accept only one missing name token when producing LSP linked-editing
ranges because the protocol requires all ranges to have identical content and
length.

## BenchmarkDotNet CLI jobs are additive

**Affected area:** Razor benchmark harnesses with jobs configured in code
**Description:** Passing `--job Dry` adds a job instead of replacing configured
jobs. This can create invalid job/toolchain combinations or concurrently rebuild
the Roslyn graph through multiple generated projects that override output paths
and race on shared assemblies. The latter can surface as timeouts, file-access
errors, or duplicate framework/polyfill type errors.
**Workaround:** Use a harness-owned validation argument that is removed before
BenchmarkDotNet parses the command line and configures exactly one Dry job. For
Razor benchmarks that reference the Roslyn project graph, use
`InProcessNoEmitToolchain` for that validation job so BenchmarkDotNet does not
generate and build a second project graph.
