knex/knex · error · Error

Can't extend ColumnBuilder with existing method ('${methodNa

Error message

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

What it means

ColumnBuilder.extend (lib/schema/columnbuilder.js:91) lets plugins add chainable methods to column definitions inside createTable/alter callbacks. It refuses to overwrite an existing own property on ColumnBuilder.prototype, so any built-in chainable (e.g. notNullable, defaultTo, references, unsigned, index, etc.) or a previously-registered extension cannot be silently replaced.

Source

Thrown at lib/schema/columnbuilder.js:95

  };

['index', 'primary', 'unique'].forEach(function (method) {
  ColumnBuilder.prototype[method] = function () {
    if (this._type.toLowerCase().indexOf('increments') === -1) {
      this._tableBuilder[method].apply(
        this._tableBuilder,
        [this._args[0]].concat(toArray(arguments))
      );
    }
    return this;
  };
});

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

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

const AlterMethods = {};

// Specify that the column is to be dropped. This takes precedence
// over all other rules for the column.
AlterMethods.drop = function () {
  this._single.drop = true;

  return this;
};

// Specify the "type" that we're looking to set the

View on GitHub (pinned to e25d54bcb7)

Solutions

  1. Namespace your method name (extend('myPluginDefault', fn)).
  2. Guard registration to be idempotent: if (!Object.prototype.hasOwnProperty.call(ColumnBuilder.prototype, name)) ColumnBuilder.extend(name, fn).
  3. Resolve the collision between the two plugins by renaming one.
  4. Inspect existing prototype methods before picking a name.

Example fix

// before
ColumnBuilder.extend('defaultTo', fn);

// after
ColumnBuilder.extend('auditDefault', fn);
Defensive patterns

Strategy: validation

Validate before calling

const { ColumnBuilder } = require('knex/lib/schema/columnbuilder');
function safeExtend(name, fn) {
  if (Object.prototype.hasOwnProperty.call(ColumnBuilder.prototype, name)) {
    throw new Error(`Refusing to clobber ColumnBuilder method: ${name}`);
  }
  ColumnBuilder.extend(name, fn);
}

Type guard

function isColumnExtendable(ColumnBuilder, name) {
  return !Object.prototype.hasOwnProperty.call(ColumnBuilder.prototype, name);
}

Try / catch

try {
  ColumnBuilder.extend(name, fn);
} catch (err) {
  if (/Can't extend ColumnBuilder/.test(err.message)) return;
  throw err;
}

Prevention

When it happens

Trigger: Calling ColumnBuilder.extend('notNullable', fn); loading two column-builder plugins that register the same method; an HMR/test setup that re-installs the same plugin twice on the same prototype.

Common situations: Plugin authors choosing common names like 'default', 'nullable', 'unique'; knex adding a new native chainable method that a plugin had already claimed under the same name in an older version.

Related errors


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