dianping/cat · error · Error

button key {key} is not allowed (options are {buttons})

Error message

button key {key} is not allowed (options are {buttons})

What it means

Each bootbox dialog type restricts which button keys are allowed (alert: 'ok'; confirm: 'confirm'/'cancel'; prompt adds input-related handling). validateButtons builds the allowed set from the type's button list and throws if options.buttons contains any other key, listing the permitted keys in the message.

Source

Thrown at cat-home/src/main/webapp/assets/js/uncompressed/bootbox.js:294

      var value = argument.toUpperCase();

      buttons[key] = {
        label: _t(value)
      };
    }

    return buttons;
  }

  function validateButtons(options, buttons) {
    var allowedButtons = {};
    each(buttons, function(key, value) {
      allowedButtons[value] = true;
    });

    each(options.buttons, function(key) {
      if (allowedButtons[key] === undefined) {
        throw new Error("button key " + key + " is not allowed (options are " + buttons.join("\n") + ")");
      }
    });

    return options;
  }

  exports.alert = function() {
    var options;

    options = mergeDialogOptions("alert", ["ok"], ["message", "callback"], arguments);

    if (options.callback && !$.isFunction(options.callback)) {
      throw new Error("alert requires callback property to be a function when provided");
    }

    /**
     * overrides
     */

View on GitHub (pinned to e815e74d4c)

Solutions

  1. Use the type's canonical keys: alert → ok; confirm → confirm and cancel; override labels via the label property, not by renaming keys.
  2. For fully custom buttons, call bootbox.dialog() instead of the typed wrappers.
  3. Keep this bootbox version's key set in mind — allowed keys differ between versions (e.g. some builds map ok/cancel aliases), so pin the version and read its source.

Example fix

// before
bootbox.confirm('Save changes?', {
  buttons: { yes: { label: 'Yes' }, no: { label: 'No' } }, callback: save
});

// after
bootbox.confirm('Save changes?', function (result) { if (result) save(); });
// or with custom labels:
bootbox.confirm({
  message: 'Save changes?', callback: function (result) { if (result) save(); },
  buttons: { confirm: { label: 'Yes' }, cancel: { label: 'No' } }
});
Defensive patterns

Strategy: validation

Validate before calling

var ALLOWED = { alert: ['ok'], confirm: ['confirm', 'cancel'], prompt: ['confirm', 'cancel'] };
function buttonsAllowedFor(type, buttons) {
  var ok = ALLOWED[type] || [];
  return Object.keys(buttons || {}).every(function (k) { return ok.indexOf(k) !== -1; });
}
if (!buttonsAllowedFor('confirm', opts.buttons)) useDialogInstead();

Type guard

function isAllowedButtonKey(type, key) {
  var allowed = { alert: ['ok'], confirm: ['confirm', 'cancel'], prompt: ['confirm', 'cancel'] };
  return (allowed[type] || []).indexOf(key) !== -1;
}

Prevention

When it happens

Trigger: bootbox.confirm('Save?', {buttons: {yes: {...}, no: {...}}}) — 'yes'/'no' are not valid for confirm; customizing an alert with a key other than 'ok'; supplying a dialog-style buttons map ({success/danger/primary from the dialog defaults}) to alert/confirm/prompt.

Common situations: Assuming all dialog types share the same button vocabulary as bootbox.dialog; copying a dialog() options block into a confirm() call; renaming button keys for readability without realizing the keys are structural identifiers, not labels.

Related errors


AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14). Data as JSON: /api/errors/d20bd5a3540e6835. Report an issue: GitHub.