dotnet/BenchmarkDotNet · error · InvalidOperationException

The ' ' environment variables is defined twice

Error message

The '{variable.Key}' environment variables is defined twice

What it means

Thrown by WithEnvironmentVariables when the provided EnvironmentVariable[] contains two entries with the same Key. The method iterates the array, tracks keys in a HashSet, and throws InvalidOperationException on the first duplicate. This prevents ambiguous environment variable definitions where the host process would only honor one of the conflicting values.

Solutions

  1. Deduplicate by key before calling, keeping the last occurrence: envVars.GroupBy(v => v.Key).Select(g => g.Last()).ToArray()
  2. Use WithEnvironmentVariable (singular) which overrides existing keys, instead of WithEnvironmentVariables (plural) which replaces all.
  3. Audit the source dictionary/list for duplicate keys before constructing EnvironmentVariable[].

Example fix

// before
var vars = new[] {
    new EnvironmentVariable("FOO", "1"),
    new EnvironmentVariable("FOO", "2"),
};
job = job.WithEnvironmentVariables(vars);

// after
var vars = new[] {
    new EnvironmentVariable("FOO", "1"),
    new EnvironmentVariable("FOO", "2"),
}.GroupBy(v => v.Key)
 .Select(g => g.Last())
 .ToArray();
job = job.WithEnvironmentVariables(vars);
Defensive patterns

Strategy: validation

Validate before calling

var deduped = environmentVariables
    .GroupBy(v => v.Key)
    .Select(g => g.Last()) // keep last occurrence (override semantics)
    .ToArray();
job = job.WithEnvironmentVariables(deduped);

Type guard

static bool HasUniqueKeys(EnvironmentVariable[] vars) =>
    vars.Select(v => v.Key).Distinct().Count() == vars.Length;

Prevention

When it happens

Trigger: Calling job.WithEnvironmentVariables(var1, var2) where var1.Key == var2.Key. The HashSet.Contains(variable.Key) check catches the second occurrence.

Common situations: Merging environment variable lists from multiple sources (e.g., base config + overrides) without deduplication. Building variables in a loop or from a dictionary where duplicate keys slip in. Configuring the same variable name twice by copy-paste.

Related errors


AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13). Data as JSON: /api/errors/d4a1b3d49f29fdf5. Report an issue: GitHub.

Appendix: source

Thrown at src/BenchmarkDotNet/Jobs/JobExtensions.cs:231

            job.WithCore(j => j.Infrastructure.BuildConfiguration = buildConfiguration);

        /// <summary>
        /// Creates a new job based on the given job with specified environment variables.
        /// It overrides the whole list of environment variables which were defined in the original job.
        /// </summary>
        /// <param name="job">The original job</param>
        /// <param name="environmentVariables">The environment variables for the new job</param>
        /// <exception cref="InvalidOperationException">
        /// Throws an exception if <paramref name="environmentVariables"/> contains two variables with the same key.
        /// </exception>
        /// <returns>The new job with overriden environment variables</returns>
        public static Job WithEnvironmentVariables(this Job job, params EnvironmentVariable[] environmentVariables)
        {
            var keys = new HashSet<string>();
            foreach (var variable in environmentVariables)
            {
                if (keys.Contains(variable.Key))
                    throw new InvalidOperationException($"The '{variable.Key}' environment variables is defined twice");
                keys.Add(variable.Key);
            }
            return job.WithCore(j => j.Environment.EnvironmentVariables = environmentVariables);
        }

        /// <summary>
        /// Creates a new job based on the given job with additional environment variable.
        /// All existed environment variables of the original job will be copied to the new one.
        /// If the original job already contains an environment variable with the same key, it will be overriden.
        /// </summary>
        /// <param name="job">The original job</param>
        /// <param name="environmentVariable">The new environment variable which should be added for the new job</param>
        /// <returns>The new job with additional environment variable</returns>
        public static Job WithEnvironmentVariable(this Job job, EnvironmentVariable environmentVariable)
            => job.WithCore(j => j.Environment.SetEnvironmentVariable(environmentVariable));

        /// <summary>
        /// Creates a new job based on the given job with additional environment variable.

View on GitHub (pinned to b515068b61)