Minimal reproduction for NestJS issue: When using parameter decorators with pipes that have injected dependencies, missing dependencies in test modules produce misleading error messages.
When using a custom parameter decorator with a pipe that has injected dependencies (via @Inject(REQUEST) or other providers), and those dependencies are not properly provided in the test module, NestJS produces misleading error messages that point to unrelated code locations rather than indicating the actual problem: missing providers for the pipe.
Key Finding: This issue is specific to the testing environment with pipes in decorators. NestJS provides helpful error messages in all other scenarios.
When a pipe's constructor dependency isn't provided in a test module, the error message:
- Points to a seemingly random line in the controller (often where the result is first used)
- Shows generic errors like
TypeError: Cannot read properties of undefined (reading 'xyz') - Provides no indication that a provider is missing
- Makes debugging extremely difficult, especially in large codebases
TypeError: Cannot read properties of undefined (reading 'assign')
at MyController.getData (my.controller.ts:17:17)
at Object.<anonymous> (my.controller.spec.ts:44:22)
This error points to logger.assign() - a completely unrelated line! It doesn't mention that GetUserPipe needs REQUEST, or that REQUEST is missing from the test providers.
The error should clearly indicate:
- That a pipe's dependency is missing
- Which pipe needs the dependency
- What dependency token is missing
- Where in the test setup to add the missing provider
Error: Cannot instantiate pipe 'GetUserPipe' in parameter decorator
Missing required provider: REQUEST (via @Inject(REQUEST))
Required by: GetUserPipe (user.decorator.ts:8)
Used in: MyController.getData (my.controller.ts:15)
Test file: my.controller.spec.ts
Suggestion: Provide both the pipe and its dependencies:
providers: [
GetUserPipe,
{
provide: REQUEST,
useValue: { /* mock request object */ }
}
]
Or override the pipe in your test:
.overridePipe(GetUserPipe)
.useValue({ transform: jest.fn() })
We tested various scenarios to identify when the confusing error happens:
| Scenario | Environment | Error Quality | Example Error |
|---|---|---|---|
| Pipe dependency missing | Testing | ❌ Confusing | TypeError: Cannot read properties of undefined (reading 'assign') at unrelated line |
| Service dependency missing | Testing | ✅ Clear | Nest can't resolve dependencies of UserService (?)... |
| Pipe dependency missing | Live/Bootstrap | ✅ Clear | Nest can't resolve dependencies of GetUserPipe (?)... |
| Service dependency missing | Live/Bootstrap | ✅ Clear | Nest can't resolve dependencies of UserService (?)... |
Conclusion: The confusing error only occurs when:
- Using a pipe with injected dependencies
- In a parameter decorator
- Within the Jest/NestJS testing module
- The dependency is missing from providers
In all other scenarios (live app, regular services), NestJS provides clear, helpful error messages during module compilation.
git clone https://github.com/mnalsup/reproduce-undefined-injects.git
cd reproduce-undefined-injects
npm install
npm testYou'll see:
- ❌
my.controller.spec.tsfails with confusing error pointing tologger.assign() - ✅
my.controller.fixed.spec.tspasses with proper mocks
user.decorator.ts- A decorator with a pipe that injectsREQUEST(30 lines)my.controller.ts- A controller using the decorator (23 lines)my.controller.spec.ts- Broken test (missing REQUEST mock)my.controller.fixed.spec.ts- Working test (with proper mocks)
When NestJS's testing module instantiates a controller with parameter decorators:
- The pipe is instantiated with its dependencies during test module compilation
- If a dependency is missing, it's set to
undefined(no compilation error!) - The test begins and the pipe executes during parameter decoration
- When the pipe tries to access properties on
undefined, it throws at runtime - The error stack trace points to where the undefined value is first used, not where the pipe dependency is missing
This differs from regular services where NestJS detects missing dependencies during module compilation and throws a clear error before any code executes.
The key difference is that in the live application, NestJS validates all dependencies during bootstrap and throws clear errors. However, in the testing environment with pipes in decorators:
- Pipes used in decorators are instantiated lazily during test execution
- The test module compiler doesn't validate pipe dependencies the same way it validates service dependencies
- The error only manifests when the pipe actually executes and tries to use
undefined
import { REQUEST } from '@nestjs/core';
import { GetUserPipe } from './user.decorator';
providers: [
GetUserPipe,
{
provide: REQUEST,
useValue: {
headers: { 'x-user-id': '1' },
},
},
].overridePipe(GetUserPipe)
.useValue({
transform: jest.fn().mockResolvedValue({ id: 1, name: 'Test User' }),
})This avoids needing to provide REQUEST at all since you're replacing the pipe implementation.
This issue significantly impacts developer experience specifically in testing:
- Wastes hours debugging misleading error messages in tests
- Makes it difficult to adopt pipes with DI in projects due to confusing test setup
- Creates confusion for developers new to NestJS testing who try to use decorators with pipes
- The real issue (missing provider) is completely obscured
- Only happens in tests, making it even more confusing (works in dev, fails in tests with unclear errors)
During test module compilation, eagerly validate that all pipe dependencies (including those in parameter decorators) are available, just like regular service dependencies. This would catch the error at compile time with a clear message.
When a pipe throws an error during execution in tests, wrap it with context about:
- Which pipe failed
- What dependencies it requires
- Where it's being used (which decorator, which parameter)
Add prominent documentation about properly mocking pipe dependencies in tests, especially for pipes used in parameter decorators.
- NestJS version: ^10.0.0
- Node version: 20.x
- Testing framework: Jest 29.x
- TypeScript version: ^5.0.0
This issue is particularly problematic when:
- Using third-party libraries that provide decorators with pipes
- Working with complex authentication/authorization flows that use custom decorators
- Onboarding new developers who aren't familiar with NestJS's DI in test contexts
- Migrating from one decorator pattern to another (e.g., switching from guards to decorator-based approaches)
- The pipe works perfectly in the live app but fails mysteriously in tests
We encountered this when adopting a third-party SDK that provided a user decorator with pipes. The app worked fine in development, but tests failed with:
TypeError: Cannot read properties of undefined (reading 'assign')
at MyController.someMethod (my.controller.ts:17:17)
It took significant debugging time to realize we needed to mock REQUEST and other services for the pipe, because the error pointed to a completely unrelated line in our controller logic.
For contrast, when we tested the same scenario with a regular service instead of a pipe:
// UserService depends on LoggerService
// Test forgets to provide LoggerServiceNestJS immediately threw a helpful error during test compilation:
Nest can't resolve dependencies of the UserService (?).
Please make sure that the argument LoggerService at index [0] is available in the RootTestModule context.
This is the quality of error message we'd like to see for pipes in decorators as well.
To submit this issue to NestJS: Copy this README content to https://github.com/nestjs/nest/issues/new and link to this reproduction repository.