userProfile.update: showcaseItems has no server-side length bound
userProfile.update accepts a showcaseItems array of any length. The client caps
it at 32; the server schema does not, so the two disagree and the cap is only
advisory.
Where
src/server/schema/user-profile.schema.ts:66
showcaseItems: z.array(showcaseItemSchema).optional(),No .max(), and this is the input schema for update: guardedProcedure
(src/server/routers/user-profile.router.ts:30).
The limit that does exist is client-side only
src/server/common/constants.ts:362—showcaseItemsLimit: 32src/components/Profile/ShowcaseItemsInput.tsx:94—if (showcaseItems.length >= limit)stops the user adding a 33rd item in the UIsrc/components/Modals/UserProfileEditModal.tsx:830— the copy tells the user "Select up to 32 items"
So the 32 is enforced in the editor, not on the write path.
It is stored unbounded
In updateUserProfile (src/server/services/user-profile.service.ts:221), showcaseItems is not
destructured out — it falls into the ...profile rest and is written straight through:
data: {
...profile,
...
}There is no length check between the tRPC input and the userProfile row.
Suggested fix
Bound it in the schema so the server agrees with the client:
showcaseItems: z.array(showcaseItemSchema).max(constants.profile.showcaseItemsLimit).optional(),Worth noting that addEntityToShowcase — the other way items get added — already truncates to the
same constant, so the schema bound would make the two entry points consistent rather than
introducing a new rule.
Why file it rather than leave a comment
Any oversized showcase already stored keeps rendering normally, so there is no user-visible symptom that would prompt someone to notice this. A code comment next to the schema line would be the obvious alternative, but nothing would ever surface it again, hence an issue.
Source: civitai/civitai