DEV Community

Cristian Sifuentes
Cristian Sifuentes

Posted on

Fixing CS0579 in .NET 10 — Why Your Assembly Attributes Are Duplicated (and How to Really Fix It)

Fixing CS0579 in .NET 10 — Why Your Assembly Attributes Are Duplicated (and How to Really Fix It)

Fixing CS0579 in .NET 10 — Why Your Assembly Attributes Are Duplicated (and How to Really Fix It)

You restore your .NET solution, everything looks good…

Then the build explodes with a wall of errors like:

error CS0579: Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute
error CS0579: Duplicate 'System.Reflection.AssemblyTitleAttribute' attribute
error CS0579: Duplicate 'System.Reflection.AssemblyVersionAttribute' attribute
Enter fullscreen mode Exit fullscreen mode

You’re not alone. This happens a LOT when:

  • You migrate an older project to SDK-style (<Project Sdk="Microsoft.NET.Sdk">), or
  • You mix legacy AssemblyInfo.cs with the new auto-generated assembly metadata.

In this article we’ll:

  • Explain exactly why CS0579 happens in modern .NET (8/9/10)
  • Show how the SDK generates AssemblyInfo for you
  • Walk through two clean fixes, depending on your scenario
  • Give you a checklist for multi-project solutions so it doesn’t come back

Treat this as a reference you can drop into your team’s internal docs or a dev.to bookmark for “that one annoying build error”.


Table of Contents

  1. What CS0579 Actually Means
  2. How SDK-Style Projects Generate Assembly Attributes
  3. Typical Scenario: ApiEcommerce Fails, Sample Project is Fine
  4. Fix Option A — Delete the Legacy AssemblyInfo.cs
  5. Fix Option B — Keep AssemblyInfo.cs and Disable Auto-Generation
  6. Building Only the Project You Care About
  7. How to Audit an Entire Solution for This Problem
  8. FAQ: .NET 10, Multi-Targeting, and CI Pipelines
  9. Conclusion

1. What CS0579 Actually Means

The compiler error is:

CS0579: Duplicate 'System.Reflection.AssemblyXxxAttribute' attribute
Enter fullscreen mode Exit fullscreen mode

That means the same assembly-level attribute is being applied more than once in your build.

Typical duplicates:

  • AssemblyCompany
  • AssemblyConfiguration
  • AssemblyFileVersion
  • AssemblyInformationalVersion
  • AssemblyProduct
  • AssemblyTitle
  • AssemblyVersion

In modern SDK-style projects, those attributes are usually defined in two places:

  1. Auto-generated file from the SDK, for example: obj/Debug/net10.0/ApiEcommerce.AssemblyInfo.cs
  2. Legacy file you still have in your repo, usually: Properties/AssemblyInfo.cs

The compiler sees both and rightly complains:

“I don’t know which company/title/version to pick — they’re duplicated.”


2. How SDK-Style Projects Generate Assembly Attributes

In old, pre-SDK projects (.csproj full of XML, packages.config, etc.), you manually maintained:

// Properties/AssemblyInfo.cs
[assembly: AssemblyTitle("ApiEcommerce")]
[assembly: AssemblyCompany("Your Company")]
[assembly: AssemblyProduct("ApiEcommerce")]
[assembly: AssemblyVersion("1.0.0.0")]
// ...
Enter fullscreen mode Exit fullscreen mode

In SDK-style projects (everything new in .NET Core / .NET 5+ / .NET 10):

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
  </PropertyGroup>
</Project>
Enter fullscreen mode Exit fullscreen mode

the .NET SDK auto-generates an AssemblyInfo file under obj on every build.

Example (generated):

// obj/Debug/net10.0/ApiEcommerce.AssemblyInfo.cs
using System.Reflection;

[assembly: AssemblyCompany("YourCompany")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ApiEcommerce")]
[assembly: AssemblyTitle("ApiEcommerce")]
[assembly: AssemblyVersion("1.0.0.0")]
Enter fullscreen mode Exit fullscreen mode

So if you keep your old Properties/AssemblyInfo.cs around with the same attributes…

you now have two versions of each attribute, and CS0579 is inevitable.


3. Typical Scenario: ApiEcommerce Fails, Sample Project is Fine

A very common pattern (maybe exactly what you saw):

  • You created a new .NET 10 console sample (e.g., CsharpDataTypesAdvanced)
  • It builds and restores just fine
  • But when you run dotnet build at the solution root, you get:
C:\...\ApiEcommerce\obj\Debug
et10.0\ApiEcommerce.AssemblyInfo.cs(15,12): error CS0579: Duplicate 'System.Reflection.AssemblyCompanyAttribute' attribute
...
Enter fullscreen mode Exit fullscreen mode

The problem is not the new sample — it’s another project in the solution: ApiEcommerce.

The fix lives entirely in that project.


4. Fix Option A — Delete the Legacy AssemblyInfo.cs

This is the simplest and most idiomatic fix for SDK-style projects.

✅ Use this when you’re okay with the SDK generating assembly metadata for you.

4.1 Verify you are using SDK-style

Open your .csproj (for example ApiEcommerce.csproj):

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <!-- other properties -->
  </PropertyGroup>

</Project>
Enter fullscreen mode Exit fullscreen mode

If you see Sdk="Microsoft.NET.Sdk", it’s SDK-style.

4.2 Find and remove the old AssemblyInfo.cs

Inside the ApiEcommerce project folder, look for:

Properties/AssemblyInfo.cs
Enter fullscreen mode Exit fullscreen mode

Open it. If you see lines like:

using System.Reflection;

[assembly: AssemblyCompany("...")]
[assembly: AssemblyConfiguration("...")]
[assembly: AssemblyFileVersion("...")]
[assembly: AssemblyInformationalVersion("...")]
[assembly: AssemblyProduct("...")]
[assembly: AssemblyTitle("...")]
[assembly: AssemblyVersion("...")]
Enter fullscreen mode Exit fullscreen mode

…you have the duplication.

Fix:

  • Either delete the file Properties/AssemblyInfo.cs, or
  • Comment out all [assembly: ...] lines if you want to keep it around temporarily.

4.3 Clean and rebuild

From the project or solution root:

dotnet clean
dotnet build
Enter fullscreen mode Exit fullscreen mode

You should see:

Build succeeded.
Enter fullscreen mode Exit fullscreen mode

No more CS0579.


5. Fix Option B — Keep AssemblyInfo.cs and Disable Auto-Generation

Sometimes you want full manual control of assembly attributes, e.g.:

  • You have complex versioning logic
  • You share one AssemblyInfo.cs across multiple projects
  • You want to keep compatibility with older tooling

In that case, you tell the SDK:

“Do not generate AssemblyInfo; I’ll handle it.”

5.1 Update your .csproj

Open ApiEcommerce.csproj and update the PropertyGroup:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>

</Project>
Enter fullscreen mode Exit fullscreen mode

This flag instructs the SDK to skip generating obj/.../AssemblyInfo.cs for that project.

5.2 Keep and maintain Properties/AssemblyInfo.cs

Keep your existing file:

// Properties/AssemblyInfo.cs
using System.Reflection;

[assembly: AssemblyTitle("ApiEcommerce")]
[assembly: AssemblyCompany("Your Company")]
[assembly: AssemblyProduct("ApiEcommerce")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// etc.
Enter fullscreen mode Exit fullscreen mode

Now, only your manual attributes are compiled; the generated ones are gone.

5.3 Clean and rebuild

dotnet clean
dotnet build
Enter fullscreen mode Exit fullscreen mode

Again, CS0579 should disappear.


6. Building Only the Project You Care About

When you’re experimenting with a new sample (e.g., CsharpDataTypesAdvanced from a C# data types article), it’s easy to forget that:

dotnet build
dotnet run
Enter fullscreen mode Exit fullscreen mode

at the solution root will:

  • Restore and compile every project in the solution
  • Including older projects like ApiEcommerce that still have configuration issues

To isolate the new project:

cd CsharpDataTypesAdvanced
dotnet restore
dotnet run
Enter fullscreen mode Exit fullscreen mode

or, if it’s part of a bigger folder structure:

cd path/to/CsharpDataTypesAdvanced
dotnet run
Enter fullscreen mode Exit fullscreen mode

This builds only that .csproj, ignoring the rest of the solution.

This is particularly useful while you’re in the middle of refactoring legacy projects but still want to play with new .NET 10 features in a clean sandbox.


7. How to Audit an Entire Solution for This Problem

On large solutions, you may want to proactively clean this up.

7.1 Find all AssemblyInfo.cs

In a shell (PowerShell example):

Get-ChildItem -Recurse -Filter AssemblyInfo.cs | Select-Object FullName
Enter fullscreen mode Exit fullscreen mode

On Linux/macOS:

find . -name "AssemblyInfo.cs"
Enter fullscreen mode Exit fullscreen mode

Review each result:

  • Is the project SDK-style?
  • Does it still need manual attributes?

7.2 Strategy per project

For each SDK-style .csproj:

  • If you don’t need custom attributes → delete AssemblyInfo.cs
  • If you do need them → add <GenerateAssemblyInfo>false</GenerateAssemblyInfo>

7.3 Add a team guideline

In your internal docs or CONTRIBUTING.md:

  • Do not add new Properties/AssemblyInfo.cs files to SDK-style projects
  • Prefer MSBuild properties (Version, Company, Product, etc.) in the .csproj instead of manual attributes when possible

8. FAQ: .NET 10, Multi-Targeting, and CI Pipelines

❓ Does this change with .NET 10?

The behavior is the same conceptually:

  • SDK-style project
  • Generated AssemblyInfo
  • Optional GenerateAssemblyInfo flag

What changes in .NET 10 are language/runtime features — not how assembly attributes are wired.

❓ What about multi-targeting (net8.0;net10.0)?

If you multi-target:

<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
Enter fullscreen mode Exit fullscreen mode

the SDK will generate separate obj/.../AssemblyInfo.cs per target.

The duplication problem is still exactly the same:

  • If you keep Properties/AssemblyInfo.csset GenerateAssemblyInfo=false
  • If you don’t need it → delete AssemblyInfo.cs

❓ Why does it fail on CI but not locally (or vice versa)?

Common reasons:

  • Locally, you’re building a single project (e.g., in Rider/VS you hit “Build” on one project).
  • On CI, dotnet build is run at the solution root, compiling everything, including legacy projects with conflicting assembly attributes.

Once you fix each project as outlined, CI should be clean.


9. Conclusion

CS0579 doesn’t mean your .NET 10 setup is broken — it means your migration is half-finished.

The core idea:

SDK-style projects auto-generate AssemblyInfo.

Legacy Properties/AssemblyInfo.cs files often duplicate those attributes.

You fix it by deciding on one source of truth:

  • Option A — Modern & simple

    Delete the old Properties/AssemblyInfo.cs and let the SDK generate everything.

  • Option B — Manual control

    Keep Properties/AssemblyInfo.cs but add

    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>

    to your .csproj.

And when you’re testing new sample projects (C# data types, Minimal APIs, Span, etc.), remember:

  • Running dotnet run in the project folder builds only that project.
  • Running dotnet build at the solution root builds everything, including older, broken projects.

Clean this up once, add a short guideline for your team, and you’ll never have to think about CS0579 again.

Happy building — and enjoy exploring .NET 10 without noisy build errors. 🚀

Top comments (0)