Skip to content

vmadm create: reject invalid brand cleanly (#1168)#1179

Draft
nwilkens wants to merge 1 commit into
TritonDataCenter:masterfrom
nwilkens:fix/issue-1168-invalid-brand-typeerror
Draft

vmadm create: reject invalid brand cleanly (#1168)#1179
nwilkens wants to merge 1 commit into
TritonDataCenter:masterfrom
nwilkens:fix/issue-1168-invalid-brand-typeerror

Conversation

@nwilkens
Copy link
Copy Markdown
Member

@nwilkens nwilkens commented May 10, 2026

Fixes #1168.

normalizePayload() runs applyZoneDefaults() (and fixPayloadMemory()) before the existing invalid-brand check. Both index BRAND_OPTIONS[brand].features.* unguarded, so an unsupported brand throws TypeError: Cannot read property 'features' of undefined and dumps core instead of returning the clean error path.

  • Move the brand-existence check above the apply-defaults branch in normalizePayload. Explicit unsupported brands now return Error: Unsupported brand: <name> via callback. No-brand and valid-brand paths are unchanged.
  • Add an assert in fixPayloadMemory so future call paths that skip upfront validation fail with a clear message rather than silently TypeError'ing on one of the ~9 unguarded BRAND_OPTIONS[brand] dereferences in this file.
  • Regression test in test-create.js calls VM.create({brand: "smartos", ...}) and asserts the callback gets Unsupported brand.

normalizePayload() applies zone defaults (which calls fixPayloadMemory
via applyZoneDefaults) before validating that the requested brand is
supported. Both helpers index BRAND_OPTIONS[brand] unguarded, so an
unknown brand crashes vmadm with:

  Uncaught TypeError: Cannot read property 'features' of undefined
   FROM
  fixPayloadMemory (/usr/vm/node_modules/VM.js)
  applyZoneDefaults (...)
  normalizePayload (...)

Hoist a brand-existence check above the apply-defaults branch so an
explicit unsupported brand returns "Unsupported brand: <name>" via
the callback instead of aborting. Add a defensive assert in
fixPayloadMemory so any future call path that bypasses validation
still surfaces a structured error rather than a TypeError.

Includes a regression test in test-create.js that calls VM.create
with brand="smartos" and asserts the callback receives a clean
"Unsupported brand" error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@danmcd
Copy link
Copy Markdown
Contributor

danmcd commented May 11, 2026

Probably beats the crud out of this (where I took a SmartOS UI json and s/joyent/smartos/g):

[root@alder-lake /var/crash/volatile]# vmadm create -f /tmp/gotcha.json 
Uncaught TypeError: Cannot read property 'features' of undefined

FROM
fixPayloadMemory (/usr/vm/node_modules/VM.js:4695:29)
applyZoneDefaults (/usr/vm/node_modules/VM.js:4977:5)
normalizePayload (/usr/vm/node_modules/VM.js:10083:9)
vasync.waterfall.vm_type (/usr/vm/node_modules/VM.js:12691:13)
Object._onImmediate (/usr/vm/node_modules/vasync/lib/vasync.js:875:12)
processImmediate [as _immediateCallback] (timers.js:330:15)
Abort (core dumped)
[root@alder-lake /var/crash/volatile]# 

Make sure you file an OS ticket for this, too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vmadm create crashes with unhelpful TypeError when given invalid brand name

2 participants