{"record":{"id":"2330126684526087","repo":"django/django","slug":"subclasses-of-storage-must-provide-a-size-method","errorCode":null,"errorMessage":"subclasses of Storage must provide a size() method","messagePattern":"subclasses of Storage must provide a size\\(\\) method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"django/core/files/storage/base.py","lineNumber":172,"sourceCode":"        \"\"\"\n        raise NotImplementedError(\n            \"subclasses of Storage must provide an exists() method\"\n        )\n\n    def listdir(self, path):\n        \"\"\"\n        List the contents of the specified path. Return a 2-tuple of lists:\n        the first item being directories, the second item being files.\n        \"\"\"\n        raise NotImplementedError(\n            \"subclasses of Storage must provide a listdir() method\"\n        )\n\n    def size(self, name):\n        \"\"\"\n        Return the total size, in bytes, of the file specified by name.\n        \"\"\"\n        raise NotImplementedError(\"subclasses of Storage must provide a size() method\")\n\n    def url(self, name):\n        \"\"\"\n        Return an absolute URL where the file's contents can be accessed\n        directly by a web browser.\n        \"\"\"\n        raise NotImplementedError(\"subclasses of Storage must provide a url() method\")\n\n    def get_accessed_time(self, name):\n        \"\"\"\n        Return the last accessed time (as a datetime) of the file specified by\n        name. The datetime will be timezone-aware if USE_TZ=True.\n        \"\"\"\n        raise NotImplementedError(\n            \"subclasses of Storage must provide a get_accessed_time() method\"\n        )\n\n    def get_created_time(self, name):","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/django/django/blob/b5388a3a80cafcce2e34196d8e81cf5b48eb33bb/django/core/files/storage/base.py#L154-L190","documentation":"Raised as NotImplementedError by the base Storage.size() abstract method. Subclasses must implement size(self, name) returning the byte size of the stored file. The base raises at storage/base.py:172.","triggerScenarios":"Calling storage.size(name) on a Storage subclass that did not override size(). Hit during file-size display in admin, validation of upload size limits, or any code calling .size() on a custom backend.","commonSituations":"Custom object-storage backend missing size(); admin templates that display file sizes triggering the abstract method; ImageField or validators that check size() before processing.","solutions":["Implement size(self, name) in the custom Storage subclass, e.g. via a HEAD request returning Content-Length.","Subclass FileSystemStorage or a complete third-party backend.","Cache size metadata to avoid repeated backend calls.","Guard callers with getattr/try-except if size is best-effort."],"exampleFix":"# before\nclass MyStorage(Storage):\n    ...\n# after\nclass MyStorage(Storage):\n    def size(self, name):\n        return self.client.head_object(Key=name).get('ContentLength', 0)","handlingStrategy":"type-guard","validationCode":"def storage_can_size(storage) -> bool:\n    return 'size' in storage.__class__.__dict__","typeGuard":"def implements_size(storage) -> bool:\n    return any('size' in c.__dict__ for c in storage.__class__.__mro__)","tryCatchPattern":"try:\n    sz = storage.size(name)\nexcept NotImplementedError:\n    sz = None  # or compute via storage.open(name) and len()","preventionTips":["Implement size(self, name) -> int in custom backends.","Guard admin/validator code that calls .size() with try/except.","Subclass a complete backend like FileSystemStorage."],"tags":["django","storage","not-implemented","subclass","size"],"backgroundTag":null,"analyzedSha":"b5388a3a80cafcce2e34196d8e81cf5b48eb33bb","analyzedAt":"2026-08-10T17:37:52.993Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}