{"record":{"id":"2366b3c4ee4e77b9","repo":"immich-app/immich","slug":"this-endpoint-can-only-be-used-with-a-session-toke","errorCode":null,"errorMessage":"This endpoint can only be used with a session token","messagePattern":"This endpoint can only be used with a session token","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/auth.service.ts","lineNumber":594,"sourceCode":"          });\n        }\n      }\n\n      return {\n        user: session.user,\n        session: {\n          id: session.id,\n          hasElevatedPermission,\n        },\n      };\n    }\n\n    throw new UnauthorizedException('Invalid user token');\n  }\n\n  async unlockSession(auth: AuthDto, dto: SessionUnlockDto): Promise<void> {\n    if (!auth.session) {\n      throw new BadRequestException('This endpoint can only be used with a session token');\n    }\n\n    const user = await this.userRepository.getForPinCode(auth.user.id);\n    this.validatePinCode(user, { pinCode: dto.pinCode });\n\n    await this.sessionRepository.update(auth.session.id, {\n      pinExpiresAt: DateTime.now().plus({ minutes: 15 }).toJSDate(),\n    });\n  }\n\n  async lockSession(auth: AuthDto): Promise<void> {\n    if (!auth.session) {\n      throw new BadRequestException('This endpoint can only be used with a session token');\n    }\n\n    await this.sessionRepository.update(auth.session.id, { pinExpiresAt: null });\n  }\n","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/immich-app/immich/blob/f48d4b332127ad365ba256108799ca8f571d2dd5/server/src/services/auth.service.ts#L576-L612","documentation":"unlockSession requires an authenticated session (cookie/bearer session), not just any auth context like an API key or shared link. If auth.session is undefined — e.g. the request authenticated via API key or another non-session mechanism — a BadRequestException is thrown.","triggerScenarios":"Calling the session-unlock endpoint authenticated with an API key or shared-link auth instead of a user session token/cookie.","commonSituations":"Automation scripts using API keys calling unlockSession; shared-link auth accidentally routed to session endpoints; missing session cookie because cookies were not forwarded by a proxy or client.","solutions":["Authenticate with a user login session (cookie or session bearer token) and retry","Do not use x-api-key auth for session unlock endpoints","Ensure the HTTP client forwards session cookies through proxies"],"exampleFix":"// before\nawait api.post('/session/unlock', dto, { headers: { 'x-api-key': key } });\n// after\nawait api.post('/session/unlock', dto, { headers: { cookie: `immich_access_token=${sessionToken}` } });","handlingStrategy":"validation","validationCode":"if (!auth.session) throw new Error('unlockSession requires a login session, not API-key auth');","typeGuard":"const hasSession = (a: AuthDto): a is AuthDto & { session: Session } => !!a.session;","tryCatchPattern":"catch (e) { if (e.status === 400 && /session token/.test(e.message)) { /* re-authenticate with session */ } }","preventionTips":["Use session auth for session-management endpoints","Forward cookies through proxies","Never substitute API keys for session flows"],"tags":["session","authentication","pin-code"],"backgroundTag":"authentication-required","analyzedSha":"f48d4b332127ad365ba256108799ca8f571d2dd5","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}