dianping/cat · error · Error
button with key {key} must be an object
Error message
button with key {key} must be an object What it means
When normalizing options.buttons, bootbox accepts either a function (short form for {callback: fn}) or an object per button key. If a button entry is neither — a string, number, array, null — it throws this Error naming the offending button key. Labels must be set via button.label, not by assigning a string to the button key itself.
Source
Thrown at cat-home/src/main/webapp/assets/js/uncompressed/bootbox.js:172
options.backdrop = options.backdrop ? "static" : false;
buttons = options.buttons;
total = getKeyLength(buttons);
each(buttons, function(key, button, index) {
if ($.isFunction(button)) {
// short form, assume value is our callback. Since button
// isn't an object it isn't a reference either so re-assign it
button = buttons[key] = {
callback: button
};
}
// before any further checks make sure by now button is the correct type
if ($.type(button) !== "object") {
throw new Error("button with key " + key + " must be an object");
}
if (!button.label) {
// the lack of an explicit label means we'll assume the key is good enough
button.label = key;
}
if (!button.className) {
if (total <= 2 && index === total-1) {
// always add a primary to the main option in a two-button dialog
button.className = "btn-primary";
} else {
button.className = "btn-default";
}
}
});
return options;View on GitHub (pinned to e815e74d4c)
Solutions
- Use the object form for custom buttons: { ok: { label: 'Yes', className: 'btn-primary', callback: fn } }.
- Use the function short form only when you need just a callback: { ok: fn }.
- When generating buttons programmatically, validate each entry: typeof b === 'function' || (b && typeof b === 'object').
Example fix
// before
bootbox.dialog({ message: 'Save?', buttons: { ok: 'Yes', cancel: 'No' } });
// after
bootbox.dialog({
message: 'Save?',
buttons: {
ok: { label: 'Yes', className: 'btn-primary', callback: save },
cancel: { label: 'No' }
}
}); Defensive patterns
Strategy: validation
Validate before calling
Object.keys(buttons).forEach(function (key) {
var b = buttons[key];
if (typeof b !== 'function' && !(b && typeof b === 'object')) {
buttons[key] = { label: String(b) }; // coerce stray strings into labels
}
}); Type guard
function isValidButtonEntry(b) {
return typeof b === 'function' || (b !== null && typeof b === 'object' && !Array.isArray(b));
} Prevention
- Button keys map to objects with label/className/callback
- Use {label: 'Yes'} not 'Yes' as the entry
- Validate programmatically generated button maps
When it happens
Trigger: buttons: { ok: 'Yes' } (string label instead of {label: 'Yes'}); buttons: { save: 1 }; buttons: { cancel: ['no'] }; a null entry from a partially populated config object.
Common situations: Assuming the buttons map takes label strings directly (common mistake from other dialog APIs); generating the buttons object from data where one record is malformed; mixing short-form functions with object entries and getting the shape wrong for one.
Related errors
- button key {key} is not allowed (options are {buttons})
- Please supply an object of options
- Please specify a message
- Invalid argument length
- alert requires callback property to be a function when provi
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/7cf5ace3a22638bb.
Report an issue: GitHub.