{"record":{"id":"6c6c02bce0614844","repo":"scrapy/scrapy","slug":"spider-not-found-spider-name","errorCode":null,"errorMessage":"Spider not found: {spider_name}","messagePattern":"Spider not found: (.+?)","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"critical","filePath":"scrapy/spiderloader.py","lineNumber":125,"sourceCode":"    @classmethod\n    def from_settings(cls, settings: BaseSettings) -> Self:\n        \"\"\"Create an instance of the class.\n\n        It's called with the current project settings, and it loads the spiders\n        found recursively in the modules of the :setting:`SPIDER_MODULES`\n        setting.\n        \"\"\"\n        return cls(settings)\n\n    def load(self, spider_name: str) -> type[Spider]:\n        \"\"\"Return the spider class for the given spider name.\n\n        If the spider name is not found, raise a :exc:`KeyError`.\n        \"\"\"\n        try:\n            return self._spiders[spider_name]\n        except KeyError:\n            raise KeyError(f\"Spider not found: {spider_name}\") from None\n\n    def find_by_request(self, request: Request) -> list[str]:\n        \"\"\"\n        Return the list of spider names that can handle the given request.\n\n        It will try to match the request's url against the domains of\n        the spiders.\n        \"\"\"\n        return [\n            name for name, cls in self._spiders.items() if cls.handles_request(request)\n        ]\n\n    def list(self) -> list[str]:\n        \"\"\"Return a list with the names of all spiders available in the project.\"\"\"\n        return list(self._spiders.keys())\n\n\nclass DummySpiderLoader:","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/scrapy/scrapy/blob/06af687662112027b4482d31e2714a3cf280a91f/scrapy/spiderloader.py#L107-L143","documentation":"Raised by SpiderLoader.load(spider_name) when the name is not in the loaded spider registry. The loader builds {name: SpiderClass} from the SPIDER_MODULES setting at startup; an unknown name re-raises as KeyError('Spider not found: ...') with the original KeyError suppressed. This is the error behind 'scrapy crawl unknown-name' style failures.","triggerScenarios":"spider_loader.load('my_spider') where 'my_spider' is not defined: spider module not listed in SPIDER_MODULES, class has no name attribute or a different name, spider file has syntax/import errors (so it never registered), or a typo in the name.","commonSituations":"Running crawls from scripts with CrawlerProcess and a mistyped name; moving spiders without updating SPIDER_MODULES; a broken import inside a spider module silently dropping it from the registry; name collisions causing unexpected names.","solutions":["List what is actually available: print(spider_loader.list()) and use one of those names","Ensure SPIDER_MODULES in settings.py contains the package holding your spider class","Fix import/syntax errors in the spider module and confirm the class defines name = 'my_spider'","Select by class instead: CrawlerProcess.crawl(MySpider) avoids name lookup"],"exampleFix":"# before\nprocess.crawl('my_spider')  # KeyError: Spider not found: my_spider\n\n# after\nfrom myproject.spiders.my import MySpider\nprocess.crawl(MySpider)","handlingStrategy":"validation","validationCode":"names = spider_loader.list()\nif spider_name not in names:\n    raise SystemExit(f'unknown spider {spider_name!r}; available: {sorted(names)}')","typeGuard":null,"tryCatchPattern":"try:\n    spider_cls = spider_loader.load(name)\nexcept KeyError as e:\n    print(f'available spiders: {spider_loader.list()}')\n    raise","preventionTips":["Validate spider names against spider_loader.list() before crawl()","Keep SPIDER_MODULES in sync with spider package layout","Crawl by class where possible","Watch startup warnings about spider loading errors"],"tags":["spider","spiderloader","configuration"],"backgroundTag":null,"analyzedSha":"06af687662112027b4482d31e2714a3cf280a91f","analyzedAt":"2026-08-15T00:21:48.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}