immich-app/immich · error · BadRequestException
Either password or pinCode is required
Error message
Either password or pinCode is required
What it means
validatePinCode requires at least one credential: if the dto contains neither `password` nor `pinCode`, there is nothing to authenticate the PIN operation with, so it throws 400 'Either password or pinCode is required'. This is a request-shape guard, not a credential check.
Solutions
- Include `pinCode` (current PIN) or `password` (account password) in the request body.
- Check the DTO field names against the current API version — a renamed field silently becomes 'missing'.
- Add client-side validation that refuses to submit the form until one of the credentials is filled.
Example fix
// before
await api.authenticationApi.changePinCode({ newPinCode });
// after
await api.authenticationApi.changePinCode({ pinCode: currentPin, newPinCode }); Defensive patterns
Strategy: validation
Validate before calling
if (!dto.pinCode && !dto.password) {
throw new Error('Provide either pinCode or password');
} Type guard
function hasPinCredential(dto: { pinCode?: string; password?: string }): dto is { pinCode: string } | { password: string } {
return Boolean(dto.pinCode || dto.password);
} Prevention
- Require the confirming credential in the form before submit.
- Validate request bodies against the current API DTO after version upgrades.
- Write tests asserting each PIN endpoint is called with a credential present.
When it happens
Trigger: Calling resetPinCode, changePinCode, or unlockSession with an empty body or a body omitting both `password` and `pinCode` fields.
Common situations: Client sending only `newPinCode` and forgetting the confirming credential; DTO field renames after an API version change leaving the old key being dropped by the serializer; partially built request objects in scripts/tests.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Invalid albumId
- Invalid assetIds
- User already has a PIN code
- User does not have a PIN code
- Asset dimensions are not available for editing
AI-assisted analysis of immich-app/immich@f48d4b3321 (2026-09-15).
Data as JSON: /api/errors/ecac01afb48e1265.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/auth.service.ts:199
private validatePinCode(
user: { pinCode: string | null; password: string | null },
dto: { pinCode?: string; password?: string },
) {
if (!user.pinCode) {
throw new BadRequestException('User does not have a PIN code');
}
if (dto.password) {
if (!this.validateSecret(dto.password, user.password)) {
throw new BadRequestException('Wrong password');
}
} else if (dto.pinCode) {
if (!this.validateSecret(dto.pinCode, user.pinCode)) {
throw new BadRequestException('Wrong PIN code');
}
} else {
throw new BadRequestException('Either password or pinCode is required');
}
}
async adminSignUp(dto: SignUpDto): Promise<UserAdminResponseDto> {
const admin = await this.createUser({
isAdmin: true,
email: dto.email,
name: dto.name,
password: dto.password,
storageLabel: 'admin',
});
return mapUserAdmin(admin);
}
async authenticate({ headers, queryParams, metadata }: ValidateRequest): Promise<AuthDto> {
const authDto = await this.validate({ headers, queryParams });
const { adminRoute, sharedLinkRoute, uri } = metadata;View on GitHub (pinned to f48d4b3321)