badges/shields · error · ErrorClass
${prettyErrorMessage}
Error message
${prettyErrorMessage} What it means
validate() runs a Joi schema over upstream/service data with abortEarly:false, and on failure throws the configured ErrorClass (typically InvalidResponse) with the prettyMessage. Its message defaults to prettyErrorMessage ('data does not match schema'); when includeKeys is set it appends the failing schema paths. This signals that the upstream data did not conform to the expected structure.
Source
Thrown at core/base-service/validate.js:38
const { error, value } = schema.validate(data, options)
if (error) {
trace.logTrace(
'validate',
emojic.womanShrugging,
traceErrorMessage,
error.message,
)
let prettyMessage = prettyErrorMessage
if (includeKeys) {
const keys = error.details.map(({ path }) => path)
if (keys) {
prettyMessage = `${prettyErrorMessage}: ${keys.join(', ')}`
}
}
throw new ErrorClass({ prettyMessage, underlyingError: error })
} else {
trace.logTrace('validate', emojic.bathtub, traceSuccessMessage, value, {
deep: true,
})
return value
}
}
export default validate
View on GitHub (pinned to 766fd8bc89)
Solutions
- Read the prettyMessage/underlyingError to see which schema paths failed (enable includeKeys).
- Fetch the raw upstream response and compare it against the service's Joi schema.
- Update the schema (or the service) for upstream API changes and file/PR the fix.
- If you operate a self-hosted provider, align its version with what the schema expects.
- Add fallback defaults for optional fields in the transform before validating.
Example fix
// before
Joi.object({ downloads: Joi.number().required() }) // data: { downloads: "1,234" } -> schema error
// after
Joi.object({ downloads: Joi.alternatives(Joi.number(), Joi.string().regex(/[\d,]+/)).required() }) Defensive patterns
Strategy: validation
Validate before calling
const { error, value } = schema.validate(data, { abortEarly: false, allowUnknown: true })
if (error) console.warn('schema paths failing:', error.details.map(d => d.path).join(', ')) Type guard
function passesSchema(data, schema) { return !schema.validate(data, { abortEarly: false }).error } Try / catch
try {
const value = validate({ ErrorClass: InvalidResponse, includeKeys: true }, data, schema)
} catch (err) {
console.error('schema mismatch on:', err.underlyingError?.details?.map(d => d.path))
return fallbackBadge
} Prevention
- Use includeKeys: true so failing paths appear in the message.
- Write contract tests with recorded upstream fixtures.
- Keep schemas in sync with upstream API changelogs.
- Prefer lenient options (allowUnknown/stripUnknown) and only require what the badge needs.
When it happens
Trigger: schema.validate(data) returns an error — any service or result whose upstream JSON is missing required fields, has wrong types (string where number), or violates a Joi rule (e.g. regex on version strings).
Common situations: Upstream API changed its response shape after a version bump, optional fields absent for some repos, date/number format differences across provider instances, self-hosted provider with older/newer schema.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- makeBadge takes an argument of type object
- Field `message` is required
- Field `${field}` must be of type string
- Field `links` must be an array of strings
- Field `links` must not have more than 2 elements
AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30).
Data as JSON: /api/errors/eafdb4ada01dea6b.
Report an issue: GitHub.