nwjs/nw.js · error · Error
'type' is immutable at runtime
Error message
'type' is immutable at runtime
What it means
Thrown by the MenuItem 'type' setter whenever any value is assigned. The native menu item is created with a fixed type at construction; changing type (e.g. normal to separator) is not supported and would invalidate the native object, so the setter always throws.
Source
Thrown at src/resources/api_nw_menuitem.js:121
util.inherits(MenuItem, EventEmitter);
MenuItem.prototype.handleGetter = function(name) {
return privates(this).option[name];
};
MenuItem.prototype.handleSetter = function(name, setter, type, value) {
value = type(value);
privates(this).option[name] = value;
nw.Obj.callObjectMethod(this.id, 'MenuItem', setter, [ value ]);
};
MenuItem.prototype.__defineGetter__('type', function() {
return this.handleGetter('type');
});
MenuItem.prototype.__defineSetter__('type', function() {
throw new Error("'type' is immutable at runtime");
});
MenuItem.prototype.__defineGetter__('label', function() {
return this.handleGetter('label');
});
MenuItem.prototype.__defineSetter__('label', function(val) {
this.handleSetter('label', 'SetLabel', String, val);
});
MenuItem.prototype.__defineGetter__('icon', function() {
return this.handleGetter('shadowIcon');
});
MenuItem.prototype.__defineSetter__('icon', function(val) {
privates(this).option.shadowIcon = String(val);
var real_path = val == '' ? '' : nwNative.getAbsolutePath(val); //FIXME
this.handleSetter('icon', 'SetIcon', String, real_path);View on GitHub (pinned to e15da848e9)
Solutions
- Create a new MenuItem of the desired type and replace it in the menu (append the new one, remove the old).
- To hide an item, use item.visible = false rather than changing its type.
Example fix
// before
item.type = 'separator';
// after
const sep = new nw.MenuItem({ type: 'separator' });
menu.insert(sep, menu.items.indexOf(item));
menu.remove(item); Defensive patterns
Strategy: validation
Validate before calling
// never assign to item.type; rebuild the item instead
Type guard
function isMutableMenuItemProp(p) { return ['label', 'icon', 'enabled', 'checked', 'tooltip', 'modifiers'].indexOf(p) !== -1; } Try / catch
try { item.type = t; } catch (e) { if (/immutable/.test(e.message)) console.warn('type is immutable; rebuild the item'); else throw e; } Prevention
- Treat type as constructor-only.
- Replace items in the menu instead of mutating their type.
When it happens
Trigger: Running `item.type = 'separator'`, `item.type = 'checkbox'`, or any assignment to .type after construction.
Common situations: Trying to toggle an item between a normal entry and a divider dynamically; porting UI code that mutated type.
Related errors
- 'type' is immutable at runtime
- Menu.items is immutable
- 'checked' property is only available for checkbox
- Menu.items is immutable
- Menu.append() requires a valid MenuItem
AI-assisted analysis of nwjs/nw.js@e15da848e9 (2026-08-13).
Data as JSON: /api/errors/af2a057213dfa629.
Report an issue: GitHub.