badges/shields · error · ValidationError
Field `${field}` must be of type string
Error message
Field `${field}` must be of type string What it means
The fields labelColor, color, message, label, and logoBase64 must be strings when present. _validate iterates these fields (badge-maker/lib/index.js:18-23) and throws if a provided value has any other typeof. This prevents malformed SVG output from numbers, booleans, or objects reaching the renderer.
Source
Thrown at badge-maker/lib/index.js:21
*/
import _makeBadge from './make-badge.js'
export class ValidationError extends Error {}
function _validate(format) {
if (format !== Object(format)) {
throw new ValidationError('makeBadge takes an argument of type object')
}
if (!('message' in format)) {
throw new ValidationError('Field `message` is required')
}
const stringFields = ['labelColor', 'color', 'message', 'label', 'logoBase64']
stringFields.forEach(function (field) {
if (field in format && typeof format[field] !== 'string') {
throw new ValidationError(`Field \`${field}\` must be of type string`)
}
})
if ('links' in format) {
if (!Array.isArray(format.links)) {
throw new ValidationError('Field `links` must be an array of strings')
} else {
if (format.links.length > 2) {
throw new ValidationError(
'Field `links` must not have more than 2 elements',
)
}
format.links.forEach(function (field) {
if (typeof field !== 'string') {
throw new ValidationError('Field `links` must be an array of strings')
}
})
}View on GitHub (pinned to 766fd8bc89)
Solutions
- Coerce the value to a string: makeBadge({ message: String(buildNumber) })
- If the value is a boolean/status, map it to a string first: message: passed ? 'passing' : 'failing'
- Validate the descriptor shape before calling makeBadge
Example fix
// before
const svg = makeBadge({ label: 'build', message: buildNumber }) // 123
// after
const svg = makeBadge({ label: 'build', message: String(buildNumber) }) Defensive patterns
Strategy: type-guard
Validate before calling
for (const f of ['labelColor', 'color', 'message', 'label', 'logoBase64']) {
if (f in badge && typeof badge[f] !== 'string') {
throw new Error(`badge field ${f} must be a string`)
}
}
const svg = makeBadge(badge) Type guard
function isBadgeStringField(v) {
return typeof v === 'string'
}
// usage: if (isBadgeStringField(badge.message)) makeBadge(badge) Try / catch
try {
return makeBadge(badge)
} catch (e) {
if (e instanceof ValidationError && e.message.includes('must be of type string')) {
const field = e.message.match(/Field `(.+)`/)[1]
return makeBadge({ ...badge, [field]: String(badge[field]) })
}
throw e
} Prevention
- Coerce numeric CI values (build numbers, percentages) with String() before use
- Map booleans to strings (passing/failing) instead of passing them raw
- Validate config-sourced badge data at load time, not at render time
When it happens
Trigger: makeBadge({ message: 42 }), makeBadge({ label: { text: 'build' } }), makeBadge({ color: true }), or makeBadge({ message: ['passing'] }) — any non-string value assigned to one of the five string fields.
Common situations: Numbers from CI (build number 123 as message), boolean success flags passed directly as message, colors read from JSON where they were numeric, or template variables that hold non-string types from an API response.
Related errors
- Field `links` must be an array of strings
- Unexpected field '${key}'. Allowed values are (${expectedKey
- makeBadge takes an argument of type object
- Field `message` is required
- Field `links` must not have more than 2 elements
AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30).
Data as JSON: /api/errors/8f2118d0b4c4859c.
Report an issue: GitHub.