Diagnosing FeathersJS Service Hooks That Do Not Run or Behave Unexpectedly
A step‑by‑step diagnostic guide to identify why FeathersJS service hooks fail to run, run at the wrong time, or produce silent failures, with checks, fixes, and escalation paths.
20 Nov 2025, 05:49 UTC

Recognizable Condition
When a FeathersJS service method is invoked, the expected logic inside a service hook (before, after, or error) either does not execute at all, runs at the wrong time, or produces silent failures such as unresolved promises or missing return values.
Cause/Diagnostic Table
| Symptom | Possible Cause |
|---|---|
| Hook console.log never appears | Hook not registered or registered for wrong method name |
| Hook runs but data is unchanged | Wrong hook type (before vs after) or hook does not return context |
| Service call hangs or returns undefined | Async hook missing return/await or throws uncaught sync error |
| Subsequent hooks are skipped | Previous hook threw an error that broke the chain |
Ordered Checks
-
Verify Hook Registration
Open the service file (e.g.,
src/services/my-service/my-service.hooks.js) and confirm the hook array exists under the correct method key.// Example: correct registration for the 'create' method module.exports = { before: { create: [ myBeforeHook ] }, after: {} };Where to run: In your editor; no special permissions needed. Expected check: The property key matches the service method you are calling (
find,get,create,update,patch,remove). Risk: Mis‑typing the method name leads to the hook never being invoked. -
Confirm Hook Type Timing
Determine whether the logic should mutate input data (before) or act on the result (after). A before hook that tries to read
hook.resultwill seeundefined.// Before hook example – works with hook.data function myBeforeHook(hook) { hook.data.processed = true; return hook; // must return hook or a promise }Where to run: Service hook file. Expected check: Hook receives
hook.datafor before,hook.resultfor after. Risk: Using the wrong timing can make the hook appear ineffective. -
Ensure Async Handling Returns a Promise
If the hook performs asynchronous work, it must either return a promise or be declared
asyncand await the work. Forgetting to return causes the hook chain to resolve immediately.// Incorrect – missing return async function badHook(hook) { await someAsyncTask(hook.data); // hook is not returned → chain ends early } // Correct async function goodHook(hook) { await someAsyncTask(hook.data); return hook; }Where to run: Hook file. Expected check: The function returns
hookor a promise that resolves tohook. Risk: Silent termination leads to missing side‑effects and no error. -
Detect Uncaught Synchronous Errors
A thrown synchronous error inside a hook aborts the chain and is propagated to the client unless caught by an error hook.
function faultyHook(hook) { if (!hook.data.name) throw new Error('Name required'); return hook; }Where to run: Hook file. Expected check: Errors are visible in the client response or in Feathers error hooks. Risk: Unhandled errors break subsequent hooks and may mask registration problems.
-
Match Hook to Correct Service Method
Ensure the hook is registered under the exact method name you are invoking. A hook registered for
findwill not run onget.// Hook registered only for 'find' module.exports = { before: { find: [ myHook ] } }; // Calling service.get(...) will skip myHookWhere to run: Service hook file. Expected check: Method name in hook registration matches the called method. Risk: Mismatch makes the hook appear never to run.
Fixes Tied to Findings
- Missing registration: Add or correct the hook array under the appropriate method key.
- Wrong hook type: Move the function to
beforeorafteras needed and ensure it reads/writes the correct hook properties. - Async handling: Make the hook
asyncand returnhook, or explicitly return a promise. - Uncaught sync error: Either handle the error inside the hook (try/catch) or let it propagate and verify error hooks capture it.
- Method mismatch: Register the hook under the exact method name or use a wildcard (
all) if it should apply to every method.
Escalation Criteria
If after performing the five checks the hook still does not behave as expected:
- Enable Feathers debug logging:
DEBUG=feathers:* npm start(or your start command). Look for lines containingfeathers:serviceandfeathers:hookto see whether the hook chain is entered. - Insert a temporary synchronous hook that throws an Error at the start of the chain. If the error does not reach the client or an error hook, the chain itself is not being invoked, indicating a deeper registration or service‑binding issue.
- Verify the service instance you are calling is the same one where hooks are defined (e.g., ensure you are not mounting the service under a different path or using a different Feathers app instance).
If the problem persists after these steps, consider reviewing the Feathers version compatibility (hooks API stable from v3.0.0) and checking for middleware that may swallow errors before they reach the hook system.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.