{"record":{"id":"05e1a33d1597dab1","repo":"immich-app/immich","slug":"skipping-invalid-file-upload-route-route","errorCode":null,"errorMessage":"Skipping invalid file upload route: ${route}","messagePattern":"Skipping invalid file upload route: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/src/middleware/file-upload.interceptor.ts","lineNumber":83,"sourceCode":"        { name: UploadFieldName.ASSET_DATA, maxCount: 1 },\n        { name: UploadFieldName.SIDECAR_DATA, maxCount: 1 },\n      ]),\n    };\n  }\n\n  async intercept(context: ExecutionContext, next: CallHandler<any>): Promise<Observable<any>> {\n    const context_ = context.switchToHttp();\n    const route = this.reflect.get<string>(PATH_METADATA, context.getClass());\n\n    const handler: RequestHandler | null = this.getHandler(route as RouteKey);\n    if (handler) {\n      await new Promise<void>((resolve, reject) => {\n        const next: NextFunction = (error) => (error ? reject(transformException(error)) : resolve());\n        const maybePromise = handler(context_.getRequest(), context_.getResponse(), next);\n        Promise.resolve(maybePromise).catch((error) => reject(error));\n      });\n    } else {\n      this.logger.warn(`Skipping invalid file upload route: ${route}`);\n    }\n\n    return next.handle();\n  }\n\n  private fileFilter(request: AuthRequest, file: Express.Multer.File, callback: multer.FileFilterCallback) {\n    try {\n      callback(null, this.assetService.canUploadFile(asUploadRequest(request, file)));\n    } catch (error: Error | any) {\n      callback(error);\n    }\n  }\n\n  private handleFile(request: AuthRequest, file: Express.Multer.File, callback: Callback<Partial<ImmichFile>>) {\n    request.on('error', (error) => {\n      if ('code' in error && error.code === 'ECONNRESET') {\n        this.logger.debug('Upload was cancelled');\n      } else {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/middleware/file-upload.interceptor.ts#L65-L101","documentation":"The file-upload interceptor only applies Multer handling to routes registered as file-upload routes. When the current route is not found in the configured file-upload routes, it logs this warning and passes the request through unmodified. It is a configuration mismatch between the interceptor registration and the actual route, not a thrown error.","triggerScenarios":"A request hits a route where intercept() cannot resolve the route path in the configured file-upload routes map, or the interceptor is applied globally to non-upload routes.","commonSituations":"Adding new upload endpoints without updating the file-upload route configuration; mounting the interceptor globally instead of per-route; typos or missing route registrations; renaming a controller route without updating config.","solutions":["Register the route in the file-upload interceptor's configured route list","Apply the interceptor only to the specific upload controllers/routes via @UseInterceptors instead of globally","Verify the route path used at runtime matches the configured route string (check controller path and method path)","If the route is intentionally not an upload route, ignore the warning"],"exampleFix":"// before\nexport class AppModule implements NestModule {\n  configure(consumer: MiddlewareConsumer) {\n    consumer.apply(FileUploadInterceptor).forRoutes('*');\n  }\n}\n// after\n@UseInterceptors(FileUploadInterceptor)\n@Controller('assets')\nexport class AssetController {\n  @Post('upload')\n  upload(@UploadedFile() file: Express.Multer.File) { ... }\n}","handlingStrategy":"validation","validationCode":"const isUploadRoute = (route: string, uploadRoutes: readonly string[]) => uploadRoutes.includes(route);\nif (!isUploadRoute(route, configuredUploadRoutes)) {\n  throw new Error(`Route ${route} is not registered for file upload — add it to the interceptor config`);\n}","typeGuard":"function isFileUploadRoute(route: string, routes: readonly string[]): route is typeof routes[number] {\n  return (routes as readonly string[]).includes(route);\n}","tryCatchPattern":null,"preventionTips":["Keep upload route configuration colocated with the controllers they target","Apply upload interceptors per-controller via @UseInterceptors rather than globally","Add an integration test that asserts every @Post(...file) endpoint passes the interceptor","When renaming routes, grep for the old path in upload-route config"],"tags":["nestjs","multer","file-upload","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}