immich-app/immich · error · Error
Schema validation failed: ${errors.join(' ')}
Error message
Schema validation failed:
${errors.join('
')} What it means
patchOpenAPI post-processes the generated OpenAPI document and validates every component schema's numeric properties. Any number-typed property must declare an explicit format (e.g. 'double') and must not use the disallowed 'float' format; violations are accumulated and thrown together as a single Error from the swagger document build in useSwagger. This enforces a project-wide convention that all OpenAPI numbers are explicitly formatted, which some client generators and strict validators require.
Source
Thrown at server/src/utils/misc.ts:264
}
if (isSchema(value) && value.type === 'number') {
if (value.format === 'float') {
errors.push(`Invalid number format: ${schemaName}.${key}=float (use double instead). `);
}
// verify it was meant to be a number (and not an integer)
if (!value.format) {
errors.push(
`${schemaName}.${key} is a number (not an integer) and requires a format (e.g .meta({ format: 'double' })). `,
);
}
}
}
schema.required?.sort();
if (errors.length > 0) {
throw new Error(`Schema validation failed:\n ${errors.join('\n ')}`);
}
}
}
for (const [key, value] of Object.entries(document.paths)) {
const newKey = key.replace('/api/', '/');
delete document.paths[key];
document.paths[newKey] = value;
}
for (const path of Object.values(document.paths)) {
const operations = {
get: path.get,
put: path.put,
post: path.post,
delete: path.delete,
options: path.options,
head: path.head,View on GitHub (pinned to 4c7b30c18b)
Solutions
- Find the offending schema.property named in the error message (format 'SchemaName.propertyKey') and add .meta({ format: 'double' }) or an explicit format to its zod/number definition
- Replace any format: 'float' with format: 'double' (float is explicitly rejected by this validator)
- If the property should be an integer, change the zod schema from z.number() to z.number().int() so it generates type:'integer' instead of type:'number'
- Re-run the server; patchOpenAPI throws on the first validation pass, so iterate until the error list is empty
Example fix
// before
z.number().meta({ description: 'Score' })
// or
z.number()
// after
z.number().meta({ description: 'Score', format: 'double' })
// or, for integers:
z.number().int() Defensive patterns
Strategy: validation
Validate before calling
// Audit all registered schemas before server start:
for (const [name, schema] of Object.entries(registry.definitions)) {
for (const [key, prop] of Object.entries((schema as any).properties ?? {})) {
const target = prop.type === 'array' ? prop.items : prop;
if (target?.type === 'number') {
if (!target.format) throw new Error(`${name}.${key} needs .meta({ format: 'double' })`);
if (target.format === 'float') throw new Error(`${name}.${key}: use 'double' not 'float'`);
}
}
} Type guard
function isSchema(v: unknown): v is SchemaObject { return typeof v === 'object' && v !== null && 'type' in v; } Try / catch
try {
useSwagger(app);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Schema validation failed:')) {
console.error('Fix these OpenAPI schemas (see each listed property):\n' + err.message);
process.exit(1); // fail fast at startup, do not serve broken docs
}
throw err;
} Prevention
- Always declare .meta({ format: 'double' }) on every z.number() used in an OpenAPI registry
- Use z.number().int() for integer fields so they emit type:'integer' and skip the number-format check
- Never use format:'float' in this codebase; it is explicitly rejected
- Run the swagger doc generation in CI (not just at server start) so schema violations fail the build
- Create shared zod schema helpers (e.g. doubleNumber()) that apply the format automatically
When it happens
Trigger: A route's response/request schema (defined via a zod-to-openapi registry or .meta() declarations) contains a property whose generated OpenAPI schema has type:'number' with either format:'float' or no format at all; the error fires when useSwagger calls patchOpenAPI on the document at startup.
Common situations: Declaring z.number() without .meta({ format: 'double' }) in an OpenAPI registry schema; using float format out of habit from other ecosystems; upgrading the framework so previously tolerated number schemas are now checked; adding a new endpoint whose DTO uses plain numbers.
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
- Failed to read helmet file: ${helmetFile}
- Invalid environment variables: \n - [${path}] ${issue.messa
- Invalid worker(s) found: ${workers.join(',')}
- Failed to decode redis options
- Invalid telemetry found: ${telemetry}
AI-assisted analysis of immich-app/immich@4c7b30c18b (2026-09-07).
Data as JSON: /api/errors/aa524e8f1ffdc756.
Report an issue: GitHub.