warpdotdev/warp · error · Error
createVariableCollection: modeNames must have at least one e
Error message
createVariableCollection: modeNames must have at least one entry.
What it means
createVariableCollection.js wraps figma.variables.createVariableCollection and requires a non-empty modeNames array, because it builds the returned modeIds map (mode name -> modeId) from that list. Figma always creates collections with a default 'Mode 1'; passing an empty list would leave no predictable mode mapping, so it is rejected up front.
Source
Thrown at resources/bundled/mcp_skills/figma/figma-generate-library/scripts/createVariableCollection.js:22
* Creates a new Figma variable collection with the specified name and modes.
* If `modeNames` has more than one entry, the first mode is renamed from
* Figma's default "Mode 1" to the first name, and additional modes are added.
*
* Every created collection is tagged with `dsb_key` plugin data so it can be
* found and cleaned up idempotently by `cleanupOrphans`.
*
* @param {string} name - The display name of the collection (e.g. "Color", "Spacing").
* @param {string[]} modeNames - Ordered list of mode names (e.g. ["Light", "Dark"] or ["Value"]).
* @param {string} [runId] - Optional dsb_run_id to tag for cleanup.
* @returns {Promise<{
* collection: VariableCollection,
* modeIds: Record<string, string>
* }>}
* `modeIds` maps each mode name to its modeId string.
*/
async function createVariableCollection(name, modeNames, runId) {
if (!modeNames || modeNames.length === 0) {
throw new Error('createVariableCollection: modeNames must have at least one entry.')
}
// Create the collection — Figma always creates it with one mode named "Mode 1".
const collection = figma.variables.createVariableCollection(name)
// Tag for idempotent cleanup
collection.setPluginData('dsb_key', `collection/${name}`)
if (runId) {
collection.setPluginData('dsb_run_id', runId)
}
// modeIds accumulator
const modeIds = {}
// Rename the default first mode
const defaultMode = collection.modes[0]
collection.renameMode(defaultMode.modeId, modeNames[0])
modeIds[modeNames[0]] = defaultMode.modeIdView on GitHub (pinned to e72fd7aacb)
Solutions
- Pass at least one mode name, e.g. ['Value'] for single-mode collections or ['Light', 'Dark'] for themed ones
- Default the parameter upstream (modeNames ?? ['Value']) and log which default was chosen
- Validate the config that produces modeNames before entering the Figma step
Example fix
// before
const modes = config.themes // undefined -> passed straight through
await createVariableCollection('Color', modes, runId) // throws
// after
const modes = Array.isArray(config.themes) && config.themes.length > 0
? config.themes
: ['Value']
await createVariableCollection('Color', modes, runId) Defensive patterns
Strategy: validation
Validate before calling
const modeNames =
Array.isArray(config.modes) && config.modes.length > 0 ? config.modes : ['Value']
await createVariableCollection('Color', modeNames, runId) Type guard
function isNonEmptyModeList(value) {
return (
Array.isArray(value) &&
value.length > 0 &&
value.every((m) => typeof m === 'string' && m.length > 0)
)
} Try / catch
try {
await createVariableCollection(name, modeNames, runId)
} catch (err) {
if (err instanceof Error && err.message.includes('modeNames must have')) {
// supply ['Value'] default or fix the config that produced modeNames
}
throw err
} Prevention
- Default missing/empty mode lists to ['Value'] at the config layer
- Validate config-derived arrays before entering Figma steps
- Log which modeNames were chosen so silent defaults are visible
When it happens
Trigger: Calling createVariableCollection(name, undefined) or createVariableCollection(name, []) — e.g. mode names derived from a config object that had no modes key, or a spread of an empty array.
Common situations: Single-mode token sets where the author forgot the conventional ['Value'] default; config-driven mode lists where the key is misspelled so the list reads as empty; refactors that dropped the modes field.
Related errors
- cleanupOrphans: runId is required.
- createSemanticTokens: mode "${modeName}" not found in modeId
- --claude-auth-secret is only valid with --harness claude.
- --codex-auth-secret is only valid with --harness codex.
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/14544c2941196ee8.
Report an issue: GitHub.