{"record":{"id":"8bb05fe95e228462","repo":"django/django","slug":"subclasses-may-provide-a-check-method-to-verify","errorCode":null,"errorMessage":"subclasses may provide a check() method to verify the finder is configured correctly.","messagePattern":"subclasses may provide a check\\(\\) method to verify the finder is configured correctly\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"django/contrib/staticfiles/finders.py","lineNumber":24,"sourceCode":"from django.contrib.staticfiles import utils\nfrom django.core.checks import Error, Warning\nfrom django.core.exceptions import ImproperlyConfigured\nfrom django.core.files.storage import FileSystemStorage, Storage, default_storage\nfrom django.utils._os import safe_join\nfrom django.utils.functional import LazyObject, empty\nfrom django.utils.module_loading import import_string\n\n# To keep track on which directories the finder has searched the static files.\nsearched_locations = []\n\n\nclass BaseFinder:\n    \"\"\"\n    A base file finder to be used for custom staticfiles finder classes.\n    \"\"\"\n\n    def check(self, **kwargs):\n        raise NotImplementedError(\n            \"subclasses may provide a check() method to verify the finder is \"\n            \"configured correctly.\"\n        )\n\n    def find(self, path, find_all=False):\n        \"\"\"\n        Given a relative file path, find an absolute file path.\n\n        If the ``find_all`` parameter is False (default) return only the first\n        found file path; if True, return a list of all found files paths.\n        \"\"\"\n        raise NotImplementedError(\n            \"subclasses of BaseFinder must provide a find() method\"\n        )\n\n    def list(self, ignore_patterns):\n        \"\"\"\n        Given an optional list of paths to ignore, return a two item iterable","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/django/django/blob/b5388a3a80cafcce2e34196d8e81cf5b48eb33bb/django/contrib/staticfiles/finders.py#L6-L42","documentation":"BaseFinder.check() raises NotImplementedError as a default. Django's system checks framework calls check() on each staticfiles finder to validate configuration; concrete finders (FileSystemFinder, AppDirectoriesFinder, DefaultStorageFinder) override it. A custom finder that subclasses BaseFinder without overriding check() triggers this only if something invokes the base check() — typically when running the system checks or collectstatic on a misbuilt custom finder.","triggerScenarios":"A custom staticfiles finder (added to STATICFILES_FINDERS) subclasses BaseFinder directly and does not override check(); then `manage.py check`, collectstatic, or findstatic runs the finder's check() and hits the NotImplementedError.","commonSituations":"Writing a custom finder (e.g., for an S3/custom storage) and forgetting the check() method; using a third-party finder package that hasn't implemented check(); a check() invocation path that doesn't catch NotImplementedError.","solutions":["Override check(self, **kwargs) in your custom finder; return a list of django.core.checks messages (often []).","Subclass a concrete finder (e.g., BaseStorageFinder) that already provides check().","If check is not applicable, define check(self, **kwargs): return []."],"exampleFix":"// before\nclass MyFinder(BaseFinder):\n    def find(self, path, find_all=False): ...\n    def list(self, ignore_patterns): ...\n    # check() missing -> NotImplementedError during `manage.py check`\n\n// after\nfrom django.core.checks import Error\nclass MyFinder(BaseFinder):\n    def find(self, path, find_all=False): ...\n    def list(self, ignore_patterns): ...\n    def check(self, **kwargs):\n        return []  # or return [Error(...)] for real checks","handlingStrategy":"type-guard","validationCode":"from django.contrib.staticfiles.finders import BaseFinder\n\ndef finder_implements_check(finder_cls) -> bool:\n    return getattr(finder_cls, 'check', None) is not getattr(BaseFinder, 'check', None)\n\n# validate all configured finders before running checks:\nfrom importlib import import_module\nfor path in settings.STATICFILES_FINDERS:\n    mod, cls = path.rsplit('.', 1)\n    assert finder_implements_check(getattr(import_module(mod), cls)), f'{path} missing check()'","typeGuard":"from django.contrib.staticfiles.finders import BaseFinder\ndef has_finder_check(finder_cls) -> bool:\n    return 'check' in finder_cls.__dict__ or any('check' in vars(b) for b in finder_cls.__mro__[1:])","tryCatchPattern":null,"preventionTips":["Subclass a concrete finder (BaseStorageFinder) that already implements check().","Always define check(self, **kwargs): return [] on custom BaseFinder subclasses.","Add a unit test that runs `manage.py check` with your custom finder enabled."],"tags":["staticfiles","finder","custom-backend","notimplementederror","system-checks"],"backgroundTag":null,"analyzedSha":"b5388a3a80cafcce2e34196d8e81cf5b48eb33bb","analyzedAt":"2026-08-10T17:37:52.993Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}