nodejs/node · error · MBErr

args_file specified multiple times in mixins for %s on %s

Error message

args_file specified multiple times in mixins for %s on %s

What it means

FlattenMixins sets vals['args_file'] from the first mixin that provides one; encountering a second mixin (in the flattened transitive set) that also sets args_file is treated as an ambiguous, unresolvable config and aborts.

Source

Thrown at deps/v8/tools/mb/mb.py:663

      'args_file': '',
      'cros_passthrough': False,
      'gn_args': '',
    }

  def FlattenMixins(self, mixins, vals, visited):
    for m in mixins:
      if m not in self.mixins:
        raise MBErr('Unknown mixin "%s"' % m)

      visited.append(m)

      mixin_vals = self.mixins[m]

      if 'cros_passthrough' in mixin_vals:
        vals['cros_passthrough'] = mixin_vals['cros_passthrough']
      if 'args_file' in mixin_vals:
        if vals['args_file']:
          raise MBErr('args_file specified multiple times in mixins '
                      'for %s on %s' %
                      (self.args.builder, self.args.builder_group))
        vals['args_file'] = mixin_vals['args_file']
      if 'gn_args' in mixin_vals:
        if vals['gn_args']:
          vals['gn_args'] += ' ' + mixin_vals['gn_args']
        else:
          vals['gn_args'] = mixin_vals['gn_args']

      if 'mixins' in mixin_vals:
        self.FlattenMixins(mixin_vals['mixins'], vals, visited)
    return vals

  def RunGNGen(self, vals, compute_grit_inputs_for_analyze=False):
    build_dir = self.args.path[0]

    cmd = self.GNCmd('gen', build_dir, '--check')
    gn_args = self.GNArgs(vals)

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Enumerate the config's transitive mixin set and locate every mixin carrying args_file.
  2. Keep args_file on exactly one mixin (or remove it from all but one).
  3. Factor the shared args_file into a single common mixin that the others depend on.

Example fix

// before
// mixin A: {'args_file': '//build/args/a.gn'}
// mixin B: {'args_file': '//build/args/b.gn'}
// config:  {'mixins': ['A', 'B']}
// after
// mixin A: {'args_file': '//build/args/a.gn'}
// mixin B: {}  (drop args_file, or merge into A)
Defensive patterns

Strategy: validation

Validate before calling

# Detect configs whose flattened mixin set has >1 args_file.
def flatten(mixin_name, seen):
    m = mixins[mixin_name]
    if 'args_file' in m:
        seen.append((mixin_name, m['args_file']))
    for sub in m.get('mixins', []):
        flatten(sub, seen)
for cfg_name, entry in configs.items():
    seen = []
    for m in (entry if isinstance(entry, list) else entry.get('mixins', [])):
        flatten(m, seen)
    assert len(seen) <= 1, f"{cfg_name} has multiple args_file: {seen}"

Prevention

When it happens

Trigger: A config whose transitive mixin closure contains two or more mixins each carrying an 'args_file' key (including via nested mixins).

Common situations: Composing reusable mixins where more than one happens to set args_file; refactor that duplicated args_file across multiple mixins; merge combining two pre-existing args_file mixins.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/6ae057fff0ce809d. Report an issue: GitHub.