immich-app/immich · error
Invalid value for 'size
Error message
Invalid value for 'size': ${pagination.size} What it means
searchSmart validates pagination.size with zod (z.int().min(1).max(1000)) before running a vector search transaction. It throws when size is not an integer between 1 and 1000, because the pgvecto.rs/vchord vector query would misbehave or return unbounded results with an invalid limit.
Solutions
- Ensure pagination.size is a positive integer between 1 and 1000 before calling searchSmart
- Coerce/parse query params with Number() and validate, or clamp: Math.min(1000, Math.max(1, size))
- Provide a sane default (e.g. 100) when the caller omits size
- Return a 400 response at the controller layer with zod validation instead of a raw Error
Example fix
// before
await searchSmart({ size: Number(req.query.size) }, options);
// after
const size = Math.min(1000, Math.max(1, Number.parseInt(req.query.size ?? '100', 10) || 100));
await searchSmart({ size }, options); Defensive patterns
Strategy: validation
Validate before calling
const parsed = z.int().min(1).max(1000).safeParse(pagination.size); if (!parsed.success) throw new BadRequestException(`size must be an integer 1-1000`);
Type guard
function isValidSize(v: unknown): v is number {
return typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 1000;
} Try / catch
try {
await searchSmart(pagination, options);
} catch (e) {
if ((e as Error).message.startsWith("Invalid value for 'size'")) {
return res.status(400).json({ error: 'size must be an integer between 1 and 1000' });
}
throw e;
} Prevention
- Always clamp page sizes: Math.min(1000, Math.max(1, size))
- Validate query params with zod at the controller boundary
- Never pass raw string query params as numeric options
- Default missing size to a fixed constant
When it happens
Trigger: Calling searchSmart with pagination.size = 0, negative, > 1000, non-integer (e.g. 10.5), or undefined/NaN.
Common situations: Clients sending missing or unparsed query params (size comes in as a string or undefined), UI paging past the allowed cap, or a caller defaulting size incorrectly.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Invalid cursor
- Invalid environment variables:
- Invalid environment variables: \n
- Invalid system config:
- Invalid system config
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/ae369f0efda7474f.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/repositories/search.repository.ts:319
}
// TODO(v4): remove with the deprecated flat-field search API
@GenerateSql({
params: [
{ page: 1, size: 200 },
{
takenAfter: DummyValue.DATE,
embedding: DummyValue.VECTOR,
lensModel: DummyValue.STRING,
withStacked: true,
isFavorite: true,
userIds: [DummyValue.UUID],
},
],
})
searchSmart(pagination: SearchPaginationOptions, options: SmartSearchOptions) {
if (!z.int().min(1).max(1000).safeParse(pagination.size).success) {
throw new Error(`Invalid value for 'size': ${pagination.size}`);
}
return this.db.transaction().execute(async (trx) => {
await sql`set local vchordrq.probes = ${sql.lit(probes[VectorIndex.Clip])}`.execute(trx);
const items = await searchAssetBuilderLegacy(trx, options)
.select(columns.searchAsset)
.innerJoin('smart_search', 'asset.id', 'smart_search.assetId')
.orderBy(sql`smart_search.embedding <=> ${options.embedding}`)
.orderBy('asset.id', 'asc')
.limit(pagination.size + 1)
.offset((pagination.page - 1) * pagination.size)
.execute();
return paginationHelper(items, pagination.size);
});
}
@GenerateSql({
params: [DummyValue.UUID],View on GitHub (pinned to e55ac299a4)