# Error Codes

> Generated by `npm run gen:errors` — do not edit by hand.

## VALIDATION

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `BAD_REQUEST` | 400 |  | Comments are not allowed on this article | Thrown at: articles/articles.service.ts:704, articles/articles.service.ts:714, articles/articles.service.ts:968, articles/articles.service.ts:974, articles/articles.service.ts:1054, articles/articles.service.ts:1062, files/files.controller.ts:126, files/files.controller.ts:137, files/files.controller.ts:177, files/files.controller.ts:185, pois/pois.service.ts:546, pois/pois.service.ts:554 | Client-side; no server action. |
| `CANNOT_TARGET_ADMIN` | 400 |  | Admin accounts cannot be deleted or anonymized | Thrown at: users/users.service.ts:1208, users/users.service.ts:1308 | Client-side; no server action. |
| `CANNOT_TARGET_SELF` | 400 |  | You cannot perform this action on your own account | Thrown at: users/users.service.ts:1200, users/users.service.ts:1312 | Client-side; no server action. |
| `CODE_EXPIRED` | 400 |  | Verification code has expired | Thrown at: users/users.service.ts:1277 | Client-side; no server action. |
| `COMPANY_REQUIRED` | 400 |  | Organizations must specify a company | Thrown at: auth/auth.service.ts:108, users/users.service.ts:387 | Client-side; no server action. |
| `FILE_TOO_LARGE` | 400 |  | The file is too large. The maximum allowed size is 50MB. | Thrown at: forum/forum.service.ts:177, forum/forum.service.ts:500, private-messages/private-messages.service.ts:48 | Client-side; no server action. |
| `INVALID_CHALLENGE` | 400 |  | Invalid or expired verification challenge | Thrown at: users/users.service.ts:1274 | Client-side; no server action. |
| `INVALID_CITY` | 400 |  | Invalid city selected for company | Thrown at: auth/auth.service.ts:132 | Client-side; no server action. |
| `INVALID_CODE` | 400 |  | Incorrect verification code | Thrown at: users/users.service.ts:1286 | Client-side; no server action. |
| `INVALID_COMPANY` | 400 |  | Invalid company selected | Thrown at: auth/auth.service.ts:120 | Client-side; no server action. |
| `INVALID_COMPANY_SELECTION` | 400 |  | Cannot specify both existing company and new company | Thrown at: auth/auth.service.ts:99 | Client-side; no server action. |
| `INVALID_COUNTRY` | 400 |  | Invalid country selected | Thrown at: auth/auth.service.ts:85, lakes/lakes.service.ts:74, lakes/lakes.service.ts:484 | Client-side; no server action. |
| `INVALID_FILE_TYPE` | 400 |  | Invalid file type. Only images (JPEG, PNG, GIF, WEBP) are allowed. | Thrown at: articles/articles.service.ts:988 | Client-side; no server action. |
| `INVALID_GEOMETRY_DATA` | 400 |  | Must provide either coordinates and longitude/latitude (for polygon) or longitude and latitude (for point). | Thrown at: pois/pois.service.ts:28, pois/pois.service.ts:37, pois/pois.service.ts:472, pois/pois.service.ts:482 | Client-side; no server action. |
| `INVALID_INPUT` | 400 |  | Either groupId (for existing conversation) or receiverId + subject (for new conversation) must be provided | Thrown at: private-messages/private-messages.service.ts:27, private-messages/private-messages.service.ts:36 | Client-side; no server action. |
| `INVALID_LAKE_TYPE` | 400 |  | Invalid lake type selected | Thrown at: lakes/lakes.service.ts:85, lakes/lakes.service.ts:496 | Client-side; no server action. |
| `INVALID_PERMISSIONS` | 400 |  | Some permissions do not exist | Thrown at: permissions/permissions.service.ts:241, permissions/permissions.service.ts:363 | Client-side; no server action. |
| `INVALID_RECEIVER_STATUS` | 400 |  | Cannot send message to inactive or deleted user | Thrown at: private-messages/private-messages.service.ts:94 | Client-side; no server action. |
| `INVALID_ROLE` | 400 |  | Invalid role selected | Thrown at: auth/auth.service.ts:90 | Client-side; no server action. |
| `INVALID_TOKEN` | 400 |  | Invalid verification token | Thrown at: auth/auth.service.ts:370, auth/auth.service.ts:502, auth/auth.service.ts:730, auth/auth.service.ts:888, users/users.service.ts:761 | Client-side; no server action. |
| `NO_CONTENT_CHANGES` | 400 |  | No content changes provided | Thrown at: moderation/moderation.service.ts:436 | Client-side; no server action. |
| `NO_FILE_PROVIDED` | 400 |  | No file provided | Thrown at: lakes/lakes.service.ts:817, users/users.service.ts:242 | Client-side; no server action. |
| `NO_FILES_PROVIDED` | 400 |  | No files provided | Thrown at: lakes/lakes.service.ts:866 | Client-side; no server action. |
| `NOT_ORGANIZATION` | 400 |  | User is not an organization | Thrown at: users/users.service.ts:1040, users/users.service.ts:1126 | Client-side; no server action. |
| `RESTORATION_EXPIRED` | 400 |  | Account restoration period has expired | Thrown at: auth/auth.service.ts:677, users/users.service.ts:707 | Client-side; no server action. |
| `SAME_EMAIL` | 400 |  | New email must be different from current email | Thrown at: auth/auth.service.ts:815 | Client-side; no server action. |
| `TOKEN_EXPIRED` | 400 |  | Verification token has expired | Thrown at: auth/auth.service.ts:375, auth/auth.service.ts:506, auth/auth.service.ts:734, auth/auth.service.ts:897, users/users.service.ts:765 | Client-side; no server action. |
| `VALIDATION_ERROR` | 400 |  | Some of the information you entered is invalid. Please review the highlighted fields. | A request failed class-validator validation (global ValidationPipe). | Client-side input problem; inspect `fields` for the offending properties. No server action needed. |

## AUTHENTICATION

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `ACCOUNT_DELETED` | 401 |  | Account has been deleted | Thrown at: utils/strategy/local.strategy.ts:24 | Client-side; no server action. |
| `EMAIL_NOT_VERIFIED` | 401 |  | Email not verified | Thrown at: utils/strategy/local.strategy.ts:21 | Client-side; no server action. |
| `INVALID_CREDENTIALS` | 401 |  | Invalid credentials | Thrown at: utils/strategy/local.strategy.ts:18 | Client-side; no server action. |
| `INVALID_PASSWORD` | 400 |  | The password you entered is incorrect. | A password confirmation/change check failed (bcrypt compare). Kept at 400 (recoverable), never 401. | Recoverable auth error; must stay 400 so the frontend does not force a logout. |
| `NOT_AUTHENTICATED` | 401 |  | You need to sign in to continue. | A protected route was reached with no authenticated session. | Expected for anonymous access to protected endpoints. |
| `SESSION_EXPIRED` | 401 |  | Your session has expired. Please sign in again. | A session cookie was present but rejected (expired/invalid) on a protected route. | Expected on idle/expired sessions; user should re-authenticate. |

## AUTHORIZATION

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `ACCESS_DENIED` | 403 |  | Access denied - you are not a participant in this group | Thrown at: private-messages/private-messages.service.ts:78, private-messages/private-messages.service.ts:408, private-messages/private-messages.service.ts:430, private-messages/private-messages.service.ts:494, private-messages/private-messages.service.ts:555, private-messages/private-messages.service.ts:857, private-messages/private-messages.service.ts:943, private-messages/private-messages.service.ts:967, private-messages/private-messages.service.ts:1027, private-messages/private-messages.service.ts:1067 | Client-side; no server action. |
| `ACCOUNT_INACTIVE` | 403 |  | User account is not active | Thrown at: utils/guards/active-user.guard.ts:15 | Client-side; no server action. |
| `FORBIDDEN` | 403 |  | You don't have permission to do that. | Authenticated user lacked the required permission/ownership. | Check the user role/permissions if the access should have been allowed. |
| `FORBIDDEN_DELETE` | 403 |  | You can only delete your own lake data | Thrown at: lake-data/lake-data.service.ts:343, pois/pois.service.ts:270 | Client-side; no server action. |
| `FORBIDDEN_LAKE_EDIT` | 403 |  | You do not have permission to edit this lake | Thrown at: lakes/lakes.service.ts:61 | Client-side; no server action. |
| `FORBIDDEN_MODERATION` | 403 |  | You do not have POI moderation permissions | Thrown at: moderation/moderation.service.ts:101, moderation/moderation.service.ts:197, moderation/moderation.service.ts:242, moderation/moderation.service.ts:546 | Client-side; no server action. |
| `FORBIDDEN_PARAMETER_ADD` | 403 |  | You can only add parameters to your own POIs | Thrown at: pois/pois.service.ts:301 | Client-side; no server action. |
| `FORBIDDEN_PARAMETER_REMOVE` | 403 |  | You can only remove parameters from your own POIs | Thrown at: pois/pois.service.ts:359 | Client-side; no server action. |
| `FORBIDDEN_UPDATE` | 403 |  | You can only update your own lake data | Thrown at: lake-data/lake-data.service.ts:239 | Client-side; no server action. |
| `NO_PERMISSION` | 403 |  | You can only view versions of your own articles | Thrown at: articles/articles.service.ts:490, articles/articles.service.ts:523, articles/articles.service.ts:644, articles/articles.service.ts:731, articles/articles.service.ts:829 | Client-side; no server action. |

## NOT_FOUND

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `ASSIGNMENT_NOT_FOUND` | 404 |  | Lake assignment not found | Thrown at: lakes/lakes.service.ts:1057 | Client-side; no server action. |
| `COMPANY_NOT_FOUND` | 400 |  | Company not found | Thrown at: users/users.service.ts:382 | Client-side; no server action. |
| `FILE_NOT_FOUND` | 404 |  | The requested file could not be found. | Thrown at: files/files.service.ts:318, files/files.service.ts:324, files/files.service.ts:354, files/files.service.ts:369, files/files.service.ts:373, files/files.service.ts:379, moderation/moderation.service.ts:492, pois/pois.service.ts:678 | Client-side; no server action. |
| `LAKE_DATA_NOT_FOUND` | 404 |  | Lake data not found | Thrown at: lake-data/lake-data.service.ts:220, lake-data/lake-data.service.ts:234, lake-data/lake-data.service.ts:338 | Client-side; no server action. |
| `LAKE_DATA_TYPE_NOT_FOUND` | 400 |  | Lake data type not found | Thrown at: lake-data/lake-data.service.ts:32, lake-data/lake-data.service.ts:262 | Client-side; no server action. |
| `LAKE_NOT_FOUND` | 404 |  | Lake not found | Thrown at: lake-data/lake-data.service.ts:21, lake-data/lake-data.service.ts:250, lakes/lakes.service.ts:474, lakes/lakes.service.ts:704, lakes/lakes.service.ts:724, lakes/lakes.service.ts:758, lakes/lakes.service.ts:825, lakes/lakes.service.ts:874, lakes/lakes.service.ts:928, lakes/lakes.service.ts:957 | Client-side; no server action. |
| `LAKE_PARAMETER_NOT_FOUND` | 400 |  | Lake parameter not found | Thrown at: pois/pois.service.ts:311 | Client-side; no server action. |
| `LAKE_TYPE_NOT_FOUND` | 404 |  | Lake type not found | Thrown at: lakes/lakes.service.ts:187, lakes/lakes.service.ts:225 | Client-side; no server action. |
| `NOT_FOUND` | 404 |  | The requested item could not be found. | A referenced resource does not exist. | Usually a stale link or deleted resource; no action needed. |
| `NOTIFICATION_NOT_FOUND` | 404 |  | Notification not found | Thrown at: notifications/notifications.service.ts:61 | Client-side; no server action. |
| `PARAMETER_NOT_FOUND` | 404 |  | Lake parameter not found | Thrown at: lakes/lakes.service.ts:1162, lakes/lakes.service.ts:1175, lakes/lakes.service.ts:1230, pois/pois.service.ts:372 | Client-side; no server action. |
| `PERMISSION_NOT_FOUND` | 404 |  | Permission not found | Thrown at: permissions/permissions.service.ts:108, permissions/permissions.service.ts:122, permissions/permissions.service.ts:164 | Client-side; no server action. |
| `POI_NOT_FOUND` | 404 |  | POI not found | Thrown at: moderation/moderation.service.ts:207, moderation/moderation.service.ts:213, pois/pois.service.ts:251, pois/pois.service.ts:265, pois/pois.service.ts:296, pois/pois.service.ts:354, pois/pois.service.ts:460, pois/pois.service.ts:655, pois/pois.service.ts:722 | Client-side; no server action. |
| `USER_NOT_FOUND` | 404 |  | The requested user could not be found. | A user lookup by id/email returned nothing. | Stale reference or deleted user. |

## CONFLICT

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `ACCOUNT_ALREADY_DELETED` | 400 |  | Account is already deleted | Thrown at: users/users.service.ts:832 | Client-side; no server action. |
| `ACCOUNT_ANONYMIZED` | 400 |  | Account has been anonymized and cannot be restored | Thrown at: auth/auth.service.ts:667, auth/auth.service.ts:746, users/users.service.ts:697, users/users.service.ts:777 | Client-side; no server action. |
| `ACCOUNT_NOT_DELETED` | 400 |  | Account is not deleted | Thrown at: auth/auth.service.ts:661, auth/auth.service.ts:741, users/users.service.ts:691, users/users.service.ts:772 | Client-side; no server action. |
| `ALREADY_ACTIVE` | 400 |  | Organization is already active | Thrown at: users/users.service.ts:1044 | Client-side; no server action. |
| `ALREADY_INACTIVE` | 400 |  | Organization is already inactive | Thrown at: users/users.service.ts:1131 | Client-side; no server action. |
| `ALREADY_VERIFIED` | 400 |  | Email is already verified | Thrown at: auth/auth.service.ts:400 | Client-side; no server action. |
| `ASSIGNMENT_EXISTS` | 400 |  | User is already assigned to this lake | Thrown at: lakes/lakes.service.ts:975 | Client-side; no server action. |
| `CATEGORY_HAS_THREADS` | 400 |  | Cannot delete category with existing threads | Thrown at: forum/forum.service.ts:135 | Client-side; no server action. |
| `CHALLENGE_ALREADY_USED` | 400 |  | This verification challenge has already been used | Thrown at: users/users.service.ts:1299 | Client-side; no server action. |
| `CONFLICT` | 409 |  | That action conflicts with the current state of the data. | Unique-constraint / duplicate / state conflict (also Prisma P2002). | Duplicate or concurrent-modification; safe to retry after resolving the conflict. NOTE: two legacy article throw sites emit this at 400 — flagged by the dev status assertion, not changed in WS1. |
| `EMAIL_IN_USE` | 400 |  | This email is already in use | Thrown at: auth/auth.service.ts:825, auth/auth.service.ts:912 | Client-side; no server action. |
| `LAKE_EXISTS` | 400 |  | A lake with this name already exists in the selected country | Thrown at: lakes/lakes.service.ts:100, lakes/lakes.service.ts:516 | Client-side; no server action. |
| `LAKE_HAS_DATA` | 400 |  | Cannot delete lake with existing data. Please remove all lake data first. | Thrown at: lakes/lakes.service.ts:730 | Client-side; no server action. |
| `LAKE_TYPE_EXISTS` | 400 |  | A lake type with this name already exists | Thrown at: lakes/lakes.service.ts:161, lakes/lakes.service.ts:201 | Client-side; no server action. |
| `LAKE_TYPE_IN_USE` | 400 |  | This lake type is in use by existing lakes and cannot be deleted. | Thrown at: lakes/lakes.service.ts:235 | Client-side; no server action. |
| `MESSAGE_READ` | 400 |  | Cannot update a message that has been read | Thrown at: private-messages/private-messages.service.ts:436 | Client-side; no server action. |
| `ORGANIZATION_DELETED` | 400 |  | Cannot activate deleted organization | Thrown at: users/users.service.ts:1049, users/users.service.ts:1137 | Client-side; no server action. |
| `PARAMETER_ALREADY_EXISTS` | 400 |  | Parameter already exists for this POI | Thrown at: pois/pois.service.ts:324 | Client-side; no server action. |
| `PARAMETER_EXISTS` | 400 |  | A parameter with this name already exists | Thrown at: lakes/lakes.service.ts:1116, lakes/lakes.service.ts:1189 | Client-side; no server action. |
| `PARAMETER_IN_USE` | 400 |  | Cannot delete parameter that is being used by POIs. Please remove it from all POIs first. | Thrown at: lakes/lakes.service.ts:1236 | Client-side; no server action. |
| `PERMISSION_EXISTS` | 400 |  | Permission already exists | Thrown at: permissions/permissions.service.ts:32 | Client-side; no server action. |
| `PERMISSION_NAME_EXISTS` | 400 |  | Permission name already exists | Thrown at: permissions/permissions.service.ts:133 | Client-side; no server action. |
| `SLUG_EXISTS` | 400 |  | Category slug already exists | Thrown at: forum/forum.service.ts:32, forum/forum.service.ts:107, forum/forum.service.ts:168, forum/forum.service.ts:400 | Client-side; no server action. |
| `THREAD_LOCKED` | 400 |  | Cannot reply to locked thread | Thrown at: forum/forum.service.ts:517, forum/forum.service.ts:692, forum/forum.service.ts:734 | Client-side; no server action. |
| `USER_ALREADY_ANONYMIZED` | 400 |  | User is already anonymized | Thrown at: users/users.service.ts:1211, users/users.service.ts:1320 | Client-side; no server action. |
| `USER_ALREADY_DELETED` | 400 |  | User is already deleted | Thrown at: users/users.service.ts:532 | Client-side; no server action. |
| `USER_ALREADY_INACTIVE` | 400 |  | User is already deactivated | Thrown at: users/users.service.ts:193 | Client-side; no server action. |
| `USER_DELETED` | 400 |  | Cannot suspend deleted user | Thrown at: users/users.service.ts:594, users/users.service.ts:642 | Client-side; no server action. |
| `USER_EXISTS` | 400 |  | An account with this email already exists. | Registration attempted with an email already in use. | Direct the user to sign in or reset their password. |

## RATE_LIMIT

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `OTP_COOLDOWN` | 400 |  | Please wait before requesting another code | Thrown at: users/users.service.ts:1220 | Client should back off. |
| `TOO_MANY_ATTEMPTS` | 400 |  | Too many attempts; request a new code | Thrown at: users/users.service.ts:1280 | Client should back off. |
| `TOO_MANY_REQUESTS` | 429 |  | Too many requests. Please wait a moment and try again. | A rate limit / cooldown was exceeded. | Client should back off; verify limiter config if unexpected. |

## MAIL

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `EMAIL_DOMAIN_INVALID` | 400 |  | That email address can't receive mail. Please check the domain and try again. | Signup MX/domain check found no mail route for the email's domain (clean ENOTFOUND/NODATA). | User typo or dead domain; fails open on transient DNS errors so this is a confident negative. |
| `MAIL_SEND_FAILED` | 500 |  | We couldn't send that email. Please try again later. | The mailer threw while sending (SMTP outage/timeout) on a flow that treats mail as required. | Check mail transport health; safe to retry. |
| `VERIFICATION_EMAIL_NOT_SENT` | 200 |  | Your account was created, but the verification email didn't go out. You can resend it. | Register succeeded but the verification email failed to send (mail outside the transaction). | Warning-only code carried on a SUCCESS payload (data.warning), never thrown. User can use Resend verification. |

## EXTERNAL

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `SERVICE_UNAVAILABLE` | 503 |  | The service is temporarily unavailable. Please try again shortly. | Database connection error (PrismaClientInitializationError / P1001 / P1017) or dependency outage. | Check DB/dependency health. Transient — client may retry. |

## INTERNAL

| code | status | aliases | user message | cause | operator note |
|---|---|---|---|---|---|
| `INTERNAL_SERVER_ERROR` | 500 | `INTERNAL_ERROR` | Something went wrong on our end. Please try again. | Unhandled server error or an explicit 500 (e.g. file save/upload failure in articles). | Look up the `ref` in error-logs; inspect stack. Requires investigation. |
| `LOGOUT_ERROR` | 500 |  | Failed to logout | Thrown at: auth/auth.service.ts:61 | Look up ref; investigate. |
| `NO_COUNTRY_AVAILABLE` | 500 |  | Cannot create the placeholder user: no country exists | Thrown at: users/users.service.ts:1336 | Look up ref; investigate. |
| `UPLOAD_FAILED` | 500 |  | Failed to upload files | Thrown at: pois/pois.service.ts:641 | Look up ref; investigate. |

