{"record":{"id":"89545497f0d1726f","repo":"scrapy/scrapy","slug":"middlewaremanager-open-spider-is-no-longer-imple","errorCode":null,"errorMessage":"MiddlewareManager.open_spider() is no longer implemented and will be removed in a future Scrapy version.","messagePattern":"MiddlewareManager\\.open_spider\\(\\) is no longer implemented and will be removed in a future Scrapy version\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"scrapy/middleware.py","lineNumber":156,"sourceCode":"        warn_deferred: bool = False,\n    ) -> _T:\n        methods = cast(\n            \"Iterable[Callable[Concatenate[_T, _P], _T]]\", self.methods[methodname]\n        )\n        for method in methods:\n            warn = global_object_name(method) if warn_deferred else None\n            if always_add_spider or (\n                add_spider and method in self._mw_methods_requiring_spider\n            ):\n                obj = await ensure_awaitable(\n                    method(obj, *(*args, self._spider)), _warn=warn\n                )\n            else:\n                obj = await ensure_awaitable(method(obj, *args), _warn=warn)\n        return obj\n\n    def open_spider(self, spider: Spider) -> Deferred[list[None]]:  # pragma: no cover\n        raise NotImplementedError(\n            \"MiddlewareManager.open_spider() is no longer implemented\"\n            \" and will be removed in a future Scrapy version.\"\n        )\n\n    def close_spider(self, spider: Spider) -> Deferred[list[None]]:  # pragma: no cover\n        raise NotImplementedError(\n            \"MiddlewareManager.close_spider() is no longer implemented\"\n            \" and will be removed in a future Scrapy version.\"\n        )\n","sourceCodeStart":138,"sourceCodeEnd":166,"githubUrl":"https://github.com/scrapy/scrapy/blob/06af687662112027b4482d31e2714a3cf280a91f/scrapy/middleware.py#L138-L166","documentation":"MiddlewareManager.open_spider() now unconditionally raises NotImplementedError. Spider open/close hooks were removed from the middleware manager API in recent Scrapy versions; middleware from_opening/start/finish handling moved elsewhere (e.g., from_crawler and engine-managed signals). The method stub exists only to break loudly for callers still using the old API.","triggerScenarios":"Calling manager.open_spider(spider) on any MiddlewareManager (SpiderMiddlewareManager or DownloaderMiddlewareManager); third-party code or tests that orchestrated crawls by manually calling open_spider.","commonSituations":"Upgrading Scrapy major versions where open_spider used to return a Deferred firing when middlewares opened; custom crawl runners built around the old manager lifecycle; stale tutorials.","solutions":["Remove calls to MiddlewareManager.open_spider(); rely on from_crawler and the engine's spider lifecycle.","Use the spider_opened signal for setup that used to happen in open_spider.","If subclassing, delete overridden open_spider implementations rather than calling super()."],"exampleFix":"# before\nmanager.open_spider(spider)  # NotImplementedError\n\n# after\nfrom scrapy import signals\ncrawler.signals.connect(self._on_open, signal=signals.spider_opened)","handlingStrategy":"validation","validationCode":"import inspect\nfrom scrapy.middleware import MiddlewareManager\n\nassert not type(manager).open_spider.__qualname__.startswith('MiddlewareManager'), \\\n    'open_spider removed; use signals'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Grep the codebase for '.open_spider(' on middleware managers before major Scrapy upgrades.","Use spider_opened signal for per-spider setup.","Watch release notes for middleware manager API changes."],"tags":["scrapy","middleware","api-removal","migration"],"backgroundTag":null,"analyzedSha":"06af687662112027b4482d31e2714a3cf280a91f","analyzedAt":"2026-08-15T00:21:48.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}