warpdotdev/warp · error · Error
createSemanticTokens: mode "${modeName}" not found in modeId
Error message
createSemanticTokens: mode "${modeName}" not found in modeIds for token "${token.name}". Available modes: ${Object.keys(modeIds).join(', ')} What it means
createSemanticTokens.js creates one Figma variable per token and sets a value for each mode, looking the modeId up in the modeIds map produced by createVariableCollection(name, modeNames). The error fires when a token's values object has a key (mode name) with no entry in modeIds — the token file and the collection's modes are out of sync. The message lists the available modes to make the mismatch obvious.
Source
Thrown at resources/bundled/mcp_skills/figma/figma-generate-library/scripts/createSemanticTokens.js:46
*/
async function createSemanticTokens(collection, modeIds, tokenMap, runId) {
const variables = {}
for (const token of tokenMap) {
// Create the variable
const variable = figma.variables.createVariable(token.name, collection, token.type)
// Tag for cleanup
variable.setPluginData('dsb_key', `variable/${token.name}`)
if (runId) {
variable.setPluginData('dsb_run_id', runId)
}
// Set values for each mode
for (const [modeName, rawValue] of Object.entries(token.values)) {
const modeId = modeIds[modeName]
if (!modeId) {
throw new Error(
`createSemanticTokens: mode "${modeName}" not found in modeIds for token "${token.name}". ` +
`Available modes: ${Object.keys(modeIds).join(', ')}`,
)
}
let value = rawValue
// Convert hex strings to Figma RGBA for COLOR type
if (token.type === 'COLOR' && typeof rawValue === 'string' && rawValue.startsWith('#')) {
value = hexToFigmaColor(rawValue)
}
variable.setValueForMode(modeId, value)
}
// Set scopes (default: empty array = hidden from property pickers / primitives)
variable.scopes = token.scopes || []
View on GitHub (pinned to e72fd7aacb)
Solutions
- Align the keys of token.values with the exact modeNames array passed to createVariableCollection (matching is case-sensitive)
- Pass the modeIds map returned by createVariableCollection straight into createSemanticTokens instead of rebuilding it
- Pre-validate that every key of every token.values exists in modeIds before creating any variable, so a mismatch does not leave a half-built collection behind
Example fix
// before
const { modeIds } = await createVariableCollection('Color', ['Light', 'Dark'], runId)
await createSemanticTokens([
{ name: 'bg/primary', type: 'COLOR', values: { light: '#ffffff', dark: '#000000' } },
], modeIds) // throws: mode "light" not found in modeIds
// after
const { modeIds } = await createVariableCollection('Color', ['Light', 'Dark'], runId)
await createSemanticTokens([
{ name: 'bg/primary', type: 'COLOR', values: { Light: '#ffffff', Dark: '#000000' } },
], modeIds) Defensive patterns
Strategy: validation
Validate before calling
const modes = Object.keys(modeIds)
for (const token of tokens) {
for (const modeName of Object.keys(token.values)) {
if (!(modeName in modeIds)) {
throw new Error(`token ${token.name} references unknown mode "${modeName}"; collection has: ${modes.join(', ')}`)
}
}
}
await createSemanticTokens(tokens, modeIds, runId) Type guard
function modesCovered(token, modeIds) {
return Object.keys(token.values).every((m) => m in modeIds)
} Try / catch
try {
await createSemanticTokens(tokens, modeIds, runId)
} catch (err) {
if (err instanceof Error && err.message.includes('not found in modeIds')) {
// re-align token.values keys with the collection's modeNames, then re-run
}
throw err
} Prevention
- Derive modeNames and token.values keys from the same config source
- Pass createVariableCollection's returned modeIds through verbatim
- Treat mode names as case-sensitive API contracts in lint checks
When it happens
Trigger: Collection created with modeNames ['Light','Dark'] but token.values keyed 'light'/'dark' (case mismatch); a token referencing a third mode like 'HighContrast' that was never passed to createVariableCollection; a modeIds map built from a different collection than the one the variable was created in.
Common situations: Design-token JSON authored separately from the pipeline config; renaming modes in the token file without updating the collection step; token sets copied from another theme system that uses 'default' instead of 'Value'.
Related errors
- createVariableCollection: modeNames must have at least one e
- cleanupOrphans: runId is required.
- Expected JSON object with 'reviews' key
- Invalid repo format: '{}'. Expected 'owner/repo' or 'https:/
- No updates requested
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/bed817181f8b79fe.
Report an issue: GitHub.