knex/knex · error · Error

Can't extend ViewBuilder with existing method ('${methodName

Error message

Can't extend ViewBuilder with existing method ('${methodName}').

What it means

ViewBuilder.extend is the plugin/extension hook (lib/schema/viewbuilder.js:82). Before assigning a new method onto the prototype it checks Object.prototype.hasOwnProperty.call(ViewBuilder.prototype, methodName); if a method with that name already exists it throws "Can't extend ViewBuilder with existing method". This prevents plugins from silently shadowing built-in or previously-registered methods.

Source

Thrown at lib/schema/viewbuilder.js:84

        return this;
      },
      defaultTo: function (defaultValue) {
        self._statements.push({
          grouping: 'alterView',
          method: 'defaultTo',
          args: [column, defaultValue],
        });
        return this;
      },
    };
  },
};

helpers.addQueryContext(ViewBuilder);

ViewBuilder.extend = (methodName, fn) => {
  if (Object.prototype.hasOwnProperty.call(ViewBuilder.prototype, methodName)) {
    throw new Error(
      `Can't extend ViewBuilder with existing method ('${methodName}').`
    );
  }

  assign(ViewBuilder.prototype, { [methodName]: fn });
};

module.exports = ViewBuilder;

View on GitHub (pinned to e25d54bcb7)

Solutions

  1. Pick a unique method name (namespace it, e.g. 'myPluginCheckOption').
  2. Remove the duplicate plugin load / guard registration with a flag.
  3. Downgrade/upgrade the plugin to a version compatible with your knex.
  4. If you truly intend to replace, delete the prototype property first (not recommended).

Example fix

// before
ViewBuilder.extend('columns', myColumns);
// after
ViewBuilder.extend('myPluginColumns', myColumns);
Defensive patterns

Strategy: validation

Validate before calling

const methodName = 'myCheckOption';
if (!Object.prototype.hasOwnProperty.call(ViewBuilder.prototype, methodName)) {
  ViewBuilder.extend(methodName, fn);
} else {
  // already registered, skip or pick a new name
}

Type guard

const isViewBuilderMethodFree = (name) =>
  !Object.prototype.hasOwnProperty.call(ViewBuilder.prototype, name);

Try / catch

try { ViewBuilder.extend('myMethod', fn); }
catch (e) {
  if (/Can't extend ViewBuilder with existing method/.test(e.message)) {
    // plugin already registered; ignore or use alternate name
  } else throw e;
}

Prevention

When it happens

Trigger: Calling ViewBuilder.extend('checkOption', fn) or any name already on ViewBuilder.prototype; loading two plugins that register the same method name; registering a plugin twice (e.g. in tests with hot-reload).

Common situations: Plugin name collision with a built-in (checkOption, columns, as, setSchema); duplicate plugin registration in a monorepo where two packages extend knex; version mismatch where a plugin registers a method that a newer knex added natively.

Related errors


AI-assisted analysis of knex/knex@e25d54bcb7 (2026-08-03). Data as JSON: /data/errors/f99ea3a75ea51a4a.json. Report an issue: GitHub.