{"record":{"id":"14544c2941196ee8","repo":"warpdotdev/warp","slug":"createvariablecollection-modenames-must-have-at-l","errorCode":null,"errorMessage":"createVariableCollection: modeNames must have at least one entry.","messagePattern":"createVariableCollection: modeNames must have at least one entry\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"resources/bundled/mcp_skills/figma/figma-generate-library/scripts/createVariableCollection.js","lineNumber":22,"sourceCode":" * Creates a new Figma variable collection with the specified name and modes.\n * If `modeNames` has more than one entry, the first mode is renamed from\n * Figma's default \"Mode 1\" to the first name, and additional modes are added.\n *\n * Every created collection is tagged with `dsb_key` plugin data so it can be\n * found and cleaned up idempotently by `cleanupOrphans`.\n *\n * @param {string} name - The display name of the collection (e.g. \"Color\", \"Spacing\").\n * @param {string[]} modeNames - Ordered list of mode names (e.g. [\"Light\", \"Dark\"] or [\"Value\"]).\n * @param {string} [runId] - Optional dsb_run_id to tag for cleanup.\n * @returns {Promise<{\n *   collection: VariableCollection,\n *   modeIds: Record<string, string>\n * }>}\n *   `modeIds` maps each mode name to its modeId string.\n */\nasync function createVariableCollection(name, modeNames, runId) {\n  if (!modeNames || modeNames.length === 0) {\n    throw new Error('createVariableCollection: modeNames must have at least one entry.')\n  }\n\n  // Create the collection — Figma always creates it with one mode named \"Mode 1\".\n  const collection = figma.variables.createVariableCollection(name)\n\n  // Tag for idempotent cleanup\n  collection.setPluginData('dsb_key', `collection/${name}`)\n  if (runId) {\n    collection.setPluginData('dsb_run_id', runId)\n  }\n\n  // modeIds accumulator\n  const modeIds = {}\n\n  // Rename the default first mode\n  const defaultMode = collection.modes[0]\n  collection.renameMode(defaultMode.modeId, modeNames[0])\n  modeIds[modeNames[0]] = defaultMode.modeId","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/warpdotdev/warp/blob/e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc/resources/bundled/mcp_skills/figma/figma-generate-library/scripts/createVariableCollection.js#L4-L40","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst modes = config.themes // undefined -> passed straight through\nawait createVariableCollection('Color', modes, runId) // throws\n\n// after\nconst modes = Array.isArray(config.themes) && config.themes.length > 0\n  ? config.themes\n  : ['Value']\nawait createVariableCollection('Color', modes, runId)","handlingStrategy":"validation","validationCode":"const modeNames =\n  Array.isArray(config.modes) && config.modes.length > 0 ? config.modes : ['Value']\nawait createVariableCollection('Color', modeNames, runId)","typeGuard":"function isNonEmptyModeList(value) {\n  return (\n    Array.isArray(value) &&\n    value.length > 0 &&\n    value.every((m) => typeof m === 'string' && m.length > 0)\n  )\n}","tryCatchPattern":"try {\n  await createVariableCollection(name, modeNames, runId)\n} catch (err) {\n  if (err instanceof Error && err.message.includes('modeNames must have')) {\n    // supply ['Value'] default or fix the config that produced modeNames\n  }\n  throw err\n}","preventionTips":["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"],"tags":["figma","design-tokens","argument-validation"],"backgroundTag":null,"analyzedSha":"e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc","analyzedAt":"2026-08-16T08:27:25.381Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}