babel/babel · error · Error

Cannot use internal helper ${name}

Error message

Cannot use internal helper ${name}

What it means

@babel/helpers marks certain helpers as internal via `helpers.isInternal(name)`. File.addHelper (file.ts:131-133) refuses to inject them because internal helpers are not meant to be emitted into user output.

Source

Thrown at packages/babel-core/src/transformation/file/file.ts:132

    //
    //   semver.satisfies("7.0.0-beta.0", `<7.0.1`) // false - surprising
    //
    // and this fails because a prerelease version can only satisfy a range
    // if it is a prerelease within the same major/minor/patch range.
    //
    // Note: If this is found to have issues, please also revisit the logic in
    // transform-runtime's definitions.js file.
    if (semver.valid(versionRange)) versionRange = `^${versionRange}`;

    return (
      !semver.intersects(`<${minVersion}`, versionRange) &&
      !semver.intersects(`>=9.0.0`, versionRange)
    );
  }

  addHelper(name: string): t.Identifier {
    if (helpers.isInternal(name)) {
      throw new Error("Cannot use internal helper " + name);
    }
    return this._addHelper(name);
  }

  _addHelper(name: string): t.Identifier {
    const declar = this.declarations[name];
    if (declar) return cloneNode(declar);

    const generator = this.get("helperGenerator");
    if (generator) {
      const res = generator(name);
      if (res) return res;
    }

    // make sure that the helper exists
    helpers.minVersion(name);

    const uid = (this.declarations[name] =

View on GitHub (pinned to 06b6eae39d)

Solutions

  1. Check `@babel/helpers` exports and only request public helper names.
  2. Implement the required runtime logic inline in your plugin rather than relying on an internal helper.
  3. Upgrade or downgrade @babel/helpers to match the @babel/core version you depend on.

Example fix

// before
const id = path.hub.addHelper('typeof'); // 'typeof' may be internal/renamed

// after: use a public helper or inline it
const id = path.hub.addHelper('interopRequireWildcard');
// or emit your own helper node directly
Defensive patterns

Strategy: validation

Validate before calling

import { isInternal } from '@babel/helpers';
function safeAddHelper(hub, name) {
  if (isInternal(name)) throw new Error(`Refusing to request internal helper: ${name}`);
  return hub.addHelper(name);
}

Type guard

import { isInternal } from '@babel/helpers';
const isPublicHelper = (name: string): boolean => !isInternal(name);

Try / catch

try {
  path.hub.addHelper(name);
} catch (err) {
  if (/Cannot use internal helper/.test(err.message)) {
    // emit the runtime logic inline instead
  }
  throw err;
}

Prevention

When it happens

Trigger: A plugin calls `path.hub.addHelper(name)` or `file.addHelper(name)` with a helper name that @babel/helpers classifies as internal.

Common situations: Writing a custom plugin that tries to reuse a private helper; mistyping a helper name so it resolves to an internal one; using an internal helper that worked in an older helpers version.

Related errors


AI-assisted analysis of babel/babel@06b6eae39d (2026-08-03). Data as JSON: /data/errors/69ba3144bccc7281.json. Report an issue: GitHub.