django/django · error · CommandError

compilemessages generated one or more errors.

Error message

compilemessages generated one or more errors.

What it means

Raised by compilemessages (django/core/management/commands/compilemessages.py:140) as a CommandError at the end of processing when self.has_errors is True. The flag is set inside compile_messages when the msgfmt subprocess (run via popen_wrapper with --check-format) reports errors for one or more .po files. This is an aggregate failure: individual file errors are printed first, then this wraps them.

Source

Thrown at django/core/management/commands/compilemessages.py:140

        self.has_errors = False
        for basedir in basedirs:
            if locales:
                dirs = [
                    os.path.join(basedir, locale, "LC_MESSAGES") for locale in locales
                ]
            else:
                dirs = [basedir]
            locations = []
            for ldir in dirs:
                for dirpath, dirnames, filenames in os.walk(ldir):
                    locations.extend(
                        (dirpath, f) for f in filenames if f.endswith(".po")
                    )
            if locations:
                self.compile_messages(locations)

        if self.has_errors:
            raise CommandError("compilemessages generated one or more errors.")

    def compile_messages(self, locations):
        """
        Locations is a list of tuples: [(directory, file), ...]
        """
        with concurrent.futures.ThreadPoolExecutor() as executor:
            futures = []
            for i, (dirpath, f) in enumerate(locations):
                po_path = Path(dirpath) / f
                mo_path = po_path.with_suffix(".mo")
                try:
                    if mo_path.stat().st_mtime >= po_path.stat().st_mtime:
                        if self.verbosity > 0:
                            self.stdout.write(
                                "File “%s” is already compiled and up to date."
                                % po_path
                            )
                        continue

View on GitHub (pinned to ae25a40be0)

Solutions

  1. Read the per-file errors printed before this message; each names the .po file and the msgfmt complaint.
  2. Open the offending .po file and fix the syntax/placeholder mismatch; ensure msgid and msgstr placeholders (%s, %d, %(...)s) match exactly.
  3. Validate plural-forms header (Content-Type, plural forms) for the locale.
  4. Re-run makemessages to regenerate a clean .po, then re-apply translations carefully.

Example fix

# before (in .po)
msgid "Welcome %s"
msgstr "Bienvenue %d"   # placeholder mismatch
# after
msgid "Welcome %s"
msgstr "Bienvenue %s"
Defensive patterns

Strategy: try-catch

Validate before calling

# validate .po placeholder parity before compiling
import re, polib  # third-party
def check_placeholders(po_path):
    for entry in polib.pofile(po_path):
        if re.findall(r'%\(.+?\)[sd]', entry.msgid) != re.findall(r'%\(.+?\)[sd]', entry.msgstr):
            return False
    return True

Try / catch

from django.core.management.base import CommandError
try:
    call_command('compilemessages')
except CommandError:
    # individual file errors were already printed; surface them in CI logs
    raise

Prevention

When it happens

Trigger: Running compilemessages when one or more .po files contain syntax errors, invalid gettext format strings, mismatched printf-style placeholders between msgid and msgstr, or encoding issues that msgfmt --check-format rejects.

Common situations: Editing .po files by hand and breaking syntax; translations with wrong plural-form headers; %s/%d placeholder count mismatch between source and translation; BOM or encoding problems in the .po file; partial machine translation output.

Related errors


AI-assisted analysis of django/django@ae25a40be0 (2026-08-06). Data as JSON: /api/errors/7e6f743f76302a0b. Report an issue: GitHub.