{"record":{"id":"6c90ca83723eb889","repo":"odoo/odoo","slug":"no-file-sent","errorCode":null,"errorMessage":"No file sent.","messagePattern":"No file sent\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"addons/base_import_module/models/ir_module.py","lineNumber":329,"sourceCode":"        ):\n            body = self.env['ir.qweb']._render(f\"{module}.welcome_article_body\", lang=self.env.user.lang)\n            article_record.write({'body': body})\n\n        mod._update_from_terp(terp)\n        _logger.info(\"Successfully imported module '%s'\", module)\n\n        if force_website_id:\n            # Restore neutralized website_id.\n            request.session['force_website_id'] = force_website_id\n\n        return True\n\n    @api.model\n    def _import_zipfile(self, module_file, force=False, with_demo=False):\n        if not self.env.is_admin():\n            raise AccessError(_(\"Only administrators can install data modules.\"))\n        if not module_file:\n            raise Exception(_(\"No file sent.\"))\n        if not zipfile.is_zipfile(module_file):\n            raise UserError(_('Only zip files are supported.'))\n\n        module_names = []\n        with zipfile.ZipFile(module_file, \"r\") as z:\n            for zf in z.infolist():\n                if zf.file_size > MAX_FILE_SIZE:\n                    raise UserError(_(\"File '%s' exceed maximum allowed file size\", zf.filename))\n\n            with file_open_temporary_directory(self.env) as module_dir:\n                manifest_files = sorted(\n                    (file.filename.split('/')[0], file)\n                    for file in z.infolist()\n                    if file.filename.count('/') == 1\n                    and file.filename.split('/')[1] in MANIFEST_NAMES\n                )\n                module_data_files = defaultdict(list)\n                dependencies = defaultdict(list)","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/odoo/odoo/blob/1e661df964b1b264c9cef3ab28430d4785be3fda/addons/base_import_module/models/ir_module.py#L311-L347","documentation":"A plain Exception (not UserError) raised by _import_zipfile when the module_file argument is falsy — i.e. the caller invoked the import API without attaching a file. Because it is a bare Exception, it typically surfaces as a traceback rather than a friendly UI message; it almost always indicates a caller bug or an empty upload.","triggerScenarios":"Calling _import_zipfile(module_file=None) / submitting the import wizard with no file selected, or an RPC payload where the 'file' key is missing or empty.","commonSituations":"Front-end form submitted before a file was chosen; HTTP file field name mismatch (server reads 'module_file' but form posts 'file'); base64 field left empty on base.import.module record.","solutions":["Attach a valid ZIP file before calling the import (validate the upload client-side)","Check the field name mapping between your form/RPC payload and module_file","Guard the call: if not module_file: skip or show a validation message instead of invoking the API"],"exampleFix":"# before\nenv['base.import.module']._import_zipfile(module_file=None)  # Exception('No file sent.')\n\n# after\nif not module_file:\n    raise UserError(_('Please select a module file to import.'))\nenv['base.import.module']._import_zipfile(module_file=module_file)","handlingStrategy":"validation","validationCode":"if not module_file or not getattr(module_file, 'read', lambda: b'')():\n    raise UserError(_('Please attach a module file.'))\nenv['base.import.module']._import_zipfile(module_file=module_file)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require the file field client-side before submit","Verify RPC payload key names","Check the uploaded size > 0"],"tags":["odoo","module-import","validation","upload"],"backgroundTag":null,"analyzedSha":"1e661df964b1b264c9cef3ab28430d4785be3fda","analyzedAt":"2026-08-15T05:22:16.142Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}