microsoft / microsoft/foundry-local
[Bug] Microsoft.AI.Foundry.Local.Core sets a global RuntimeIdentifier in buildTransitive, silently making consuming apps RID-specific
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 2.6k
- Forks
- 369
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 39
Description
### Describe the issue
`buildTransitive/Microsoft.AI.Foundry.Local.Core.targets` pins the consuming project's RuntimeIdentifier to the build machine's RID. The file's entire contents:
```
$(NETCoreSdkRuntimeIdentifier)
```
For a portable app that ships to more than one architecture this is silently destructive. It flips the whole project from portable to RID-specific, which changes how NuGet resolves native assets: they stop arriving as `RuntimeTargetsCopyLocalItems` destined for runtimes//native/ and instead arrive as `NativeCopyLocalItems` flattened into the output root, for one architecture only.
The failure is maximally delayed. The build succeeds, the installer succeeds, and the app dies on first launch on any machine whose architecture isn't the build agent's: because deps.json is still generated portable, with per-RID runtimeTargets entries. The host looks for e.g. runtimes/win-arm64/native/libSkiaSharp.dll, doesn't find it, falls back to the app directory, and loads the x64 copy the build left there. `BadImageFormatException`.
### To reproduce
```
net10.0-windows
win-x64;win-arm64
```
```
msbuild App.csproj -t:ResolvePackageAssets -getProperty:RuntimeIdentifier
msbuild App.csproj -t:ResolvePackageAssets -getItem:NativeCopyLocalItems,RuntimeTargetsCopyLocalItems
```
| | without the package | with it |
|---------------------------------|--------------------------------------------------------------------------------------|----------------------|
| RuntimeIdentifier after targets | (empty) | win-x64 (the host's) |
| item group | RuntimeTargetsCopyLocalItems | NativeCopyLocalItems |
| DestinationSubPath | runtimes\win-x64\native\libSkiaSharp.dll, runtimes\win-arm64\native\libSkiaSharp.dll | libSkiaSharp.dll |
Note RuntimeIdentifier evaluates empty and only becomes non-empty after targets run, so -getProperty without -t: won't show it. MSBUILDLOGPROPERTYTRACKING=15 attributes it to the package's targets file.
### Urgency
Why this is a packaging bug, not a preference
1. A library shouldn't set a global property that redefines its consumer's build: asset resolution, output layout and deps.json all change, none of it requested.
2. It's in buildTransitive, the widest possible reach, so it hits projects that never referenced the package. In our case the PackageReference was on a library; the damage landed in the application project several hops away.
3. Defaulting to the build host's RID is wrong for anything built once and shipped to many architectures. CI agents are overwhelmingly x64; users increasingly are not.
4. Condition="'$(RuntimeIdentifier)'==''" means it's invisible to anyone already setting a RID; i.e. it only fires on exactly the projects it will break.
**Workaround**:
This must be applied to every project that produces a payload, not just the one with the direct reference. The targets flow transitively through ProjectReference. Nothing is lost; that six-line targets file is the package's entire build contribution.
### Platform and architecture
Windows ARM64
### OS Version
Any
### Installation type
Released package/binary
### Foundry Local version
1.2.5
### API or surface area
C# SDK
### Hardware acceleration/backend
Other / Unknown
### Backend/runtime version
Doesn't matter
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
Start with buildTransitive/Microsoft.AI.Foundry.Local.Core.targets, then run the listed MSBuild ResolvePackageAssets commands against the reproduction project. Verify that consuming projects no longer receive a host-derived RuntimeIdentifier and that SkiaSharp assets remain in RuntimeTargetsCopyLocalItems with per-RID paths for win-x64 and win-arm64.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100