odoo/odoo · error · UserError

The sending of invoices is not set up properly, make sure th

Error message

The sending of invoices is not set up properly, make sure the report used is set for invoices.

What it means

_check_invoice_report guards the send/generate flow: it fails when a report passed via custom_settings['pdf_report'] is not available for one of the moves, or when the resolved default report does not have is_invoice_report True. The point is that invoice sending must use a report declared as an invoice report (correct model and paperformat binding).

Source

Thrown at addons/account/models/account_move_send.py:353

    @api.model
    def _get_move_constraints(self, move):
        constraints = {}
        if move.state != 'posted':
            constraints['not_posted'] = _("You can't generate invoices that are not posted.")
        if not move.is_sale_document(include_receipts=True):
            constraints['not_sale_document'] = _("You can only generate sales documents.")
        return constraints

    @api.model
    def _check_invoice_report(self, moves, **custom_settings):
        if ((
                custom_settings.get('pdf_report')
                and any(not move._is_action_report_available(custom_settings['pdf_report']) for move in moves)
            )
            or any(not self._get_default_pdf_report_id(move).is_invoice_report for move in moves)
        ):
            raise UserError(_("The sending of invoices is not set up properly, make sure the report used is set for invoices."))

    @api.model
    def _format_error_text(self, error):
        """ Format the error that can be a dict (complex format needed)

        :param error: the error to format.
        :return: a text formatted error.
        """
        errors = '\n- '.join(error.get('errors', ''))
        return f"{error['error_title']}\n- {errors}" if errors else error['error_title']

    @api.model
    def _format_error_html(self, error):
        """ Format the error that can be a dict (complex format needed)

        :param error: the error to format.
        :return: a html formatted error.
        """

View on GitHub (pinned to 1e661df964)

Solutions

  1. Pass a proper invoice report: verify report.is_invoice_report and report.model == 'account.move' before using it in custom_settings.
  2. Fix the custom report definition so it is registered as an invoice report (binding_model_id account.move / is_invoice_report), then re-run the send.
  3. If no explicit report is wanted, clear the wrong pdf_report from custom_settings and let defaults resolve.

Example fix

// before
settings = {'pdf_report': generic_report}  # not an invoice report
send._send_invoice(move, **settings)

// after
assert generic_report.is_invoice_report and generic_report.model == 'account.move'
settings = {'pdf_report': generic_report}
send._send_invoice(move, **settings)
Defensive patterns

Strategy: validation

Validate before calling

report = custom_settings.get('pdf_report') or env['account.move.send']._get_default_pdf_report_id(move)
assert report.is_invoice_report and all(move._is_action_report_available(report) for move in moves)

Prevention

When it happens

Trigger: Calling account.move.send actions with custom_settings {'pdf_report': some_report} where some_report is unavailable for a move, or default template resolution (see error 135) returning a report with is_invoice_report False — e.g. a generic document report bound to another model.

Common situations: Integrations passing an arbitrary ir.actions.report id to the send wizard; custom PDF report modules that forget to set the invoice report flag / binding model account.move; mixing refund or delivery-slip reports into invoice sending.

Related errors


AI-assisted analysis of odoo/odoo@1e661df964 (2026-08-15). Data as JSON: /api/errors/d0f9b2c0202bbeb0. Report an issue: GitHub.