Guide
Troubleshooting
Symptoms that have no error message attached, and where to look for each.
Most problems here announce themselves — a validation error, a permission refusal, a stack trace. The ones below historically did not, because a decorator that never ran produces no request to fail. Several now report themselves at boot; where that is the case it says so.
Symptom index
| Symptom | Cause | Where |
|---|---|---|
| Decorators do nothing, or behave oddly | experimentalDecorators not set | Getting started — now throws with a clear message |
| No models, empty schema, no routes | importFiles looked for .js and found only .ts | Warns at boot with the extensions it wants |
| Every class registered twice | importFiles ran over compiled and source copies | Warns, naming the class |
| A trigger never fires | Declared on a class without @ParseClass | Triggers — warns, naming the class |
| Writes land outside a transaction | directAccess not true | Transactions |
A Pointer is ignored by fromParams | No targetClass, or the class is excluded by configuration | Models — Pointer without a target throws at import |
| An array of pointers stays raw | The Array field has no targetClass | Field options |
| Typed property access unavailable | A query result was not cast to the model | Models |
| Cron jobs never run | node-cron not installed | Warns at boot |
| Optimistic locking has no effect | Adapter not wired in, or running on Postgres | Optimistic locking — warns at boot |
An endpoint is reachable with no session, despite requiresAuth: true | Fixed in 3.0.0. Before that the flag was read only by the OpenAPI renderer — the endpoint was open while the docs drew a padlock on it. Upgrade, or use validation: {requireUser: true}. | |
| A rate limit never fires | Fixed in 3.0.0. The limiter was applied only on the entity route, so a caller asking for /functions/{name} directly skipped it. Note the declared methods apply to the entity route only, by design — Parse.Cloud.run always POSTs to /functions. | |
| A valid master key is refused | Nothing configured to compare it against | Configuration |
| A query returns nothing, but the data exists | The ACL filtered every row | Queries — re-run with the master key to confirm |
| Only 100 rows come back | That is the default limit | Queries |
A pointer comes back as {__type: 'Pointer'} | No include() for it | Queries |
| A row is visible to everyone | No ACL was set, so the class default applied — which is public unless declared | Permissions & ACL |
| An image is invisible while its record is public | syncImageAcl not called after the parent's ACL was set | Files & images |
| A private file is reachable by URL | File URLs are not ACL-protected | Files & images |
| Password reset email never arrives | No email adapter, or publicServerURL unset | Users & auth |
| A revoked role still works | The role cache is on and was not invalidated | Users & auth |
| A user can edit another user | Saved with the master key instead of the caller's session token | Users & auth |
| Unique indexes vanish after a restart | parse-server < 8.3, or keepUnknownIndexes off | Defaults protective since 2.8 |
Traps that no longer exist
Two were removed rather than documented, because a warning is not a fix:
Fields reading undefined |
A class field could shadow @ParseField's accessor at target: ES2022 — reads returned undefined, and writes landed on the instance so save() sent nothing. @ParseClass now repairs it, whatever the compiler settings. |
| Decorator order | @Transactional() above @CloudFunction meant the transaction never opened. The registry now re-reads the method when it registers it, so either order works. |
When something will not start
- Is
experimentalDecoratorsset? - Did
importFilesprint the files it loaded — and are they the compiled ones? - Did the registries initialise after Parse Server was mounted?
- Read the boot output for
[Triggers],[Indexes],[Versioning]and[Cron]lines. Most of what used to be silent now appears there.