badges/shields · error · ValidationError

Field `style` must be one of (${styleValues.toString()})

Error message

Field `style` must be one of (${styleValues.toString()})

What it means

The optional `style` field controls the badge's visual template and must be one of: plastic, flat, flat-square, for-the-badge, social. _validate checks styleValues.includes(format.style) (badge-maker/lib/index.js:49) and throws, listing all allowed values in the message. Unsupported/legacy style names are rejected before rendering.

Source

Thrown at badge-maker/lib/index.js:50

        )
      }
      format.links.forEach(function (field) {
        if (typeof field !== 'string') {
          throw new ValidationError('Field `links` must be an array of strings')
        }
      })
    }
  }

  const styleValues = [
    'plastic',
    'flat',
    'flat-square',
    'for-the-badge',
    'social',
  ]
  if ('style' in format && !styleValues.includes(format.style)) {
    throw new ValidationError(
      `Field \`style\` must be one of (${styleValues.toString()})`,
    )
  }
  if ('idSuffix' in format && !/^[a-zA-Z0-9\-_]*$/.test(format.idSuffix)) {
    throw new ValidationError(
      'Field `idSuffix` must contain only numbers, letters, -, and _',
    )
  }
}

function _clean(format) {
  const expectedKeys = [
    'label',
    'message',
    'labelColor',
    'color',
    'style',
    'logoBase64',

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Use one of the exact allowed values: 'plastic' | 'flat' | 'flat-square' | 'for-the-badge' | 'social'
  2. Default/normalize the style when user input: style: allowedStyles.includes(s) ? s : 'flat'
  3. Check spelling/kebab-case against the list in the error message

Example fix

// before
const svg = makeBadge({ message: 'passing', style: 'flatSquare' })
// after
const svg = makeBadge({ message: 'passing', style: 'flat-square' })
Defensive patterns

Strategy: validation

Validate before calling

const STYLES = ['plastic', 'flat', 'flat-square', 'for-the-badge', 'social']
if ('style' in badge && !STYLES.includes(badge.style)) {
  badge.style = 'flat'
}
const svg = makeBadge(badge)

Type guard

/** @returns {v is 'plastic'|'flat'|'flat-square'|'for-the-badge'|'social'} */
function isValidStyle(v) {
  return ['plastic', 'flat', 'flat-square', 'for-the-badge', 'social'].includes(v)
}

Try / catch

try {
  return makeBadge(badge)
} catch (e) {
  if (e instanceof ValidationError && e.message.startsWith('Field `style`')) {
    return makeBadge({ ...badge, style: 'flat' })
  }
  throw e
}

Prevention

When it happens

Trigger: makeBadge({ message: 'x', style: 'flat-squared' }), style: 'default', style: 'plastic2', or any typo'd/custom style string not in the five-value whitelist.

Common situations: Typos in style names, migrating from shields' old styles that were removed (e.g. some legacy styles from gh-badges), building style from user input without whitelisting, or camelCase vs kebab-case confusion ('flatSquare' vs 'flat-square').

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30). Data as JSON: /api/errors/36a44e5f10f7d6f8. Report an issue: GitHub.