{"record":{"id":"aabc1f2bb2551e57","repo":"cakephp/cakephp","slug":"invalid-format-for-mo-translations-file","errorCode":null,"errorMessage":"Invalid format for MO translations file","messagePattern":"Invalid format for MO translations file","errorType":"exception","errorClass":"CakeException","httpStatus":null,"severity":"error","filePath":"src/I18n/Parser/MoFileParser.php","lineNumber":70,"sourceCode":"    /**\n     * Parses machine object (MO) format, independent of the machine's endian it\n     * was created on. Both 32bit and 64bit systems are supported.\n     *\n     * @param string $file The file to be parsed.\n     * @return array List of messages extracted from the file\n     * @throws \\Cake\\Core\\Exception\\CakeException If stream content has an invalid format.\n     */\n    public function parse(string $file): array\n    {\n        $stream = fopen($file, 'rb');\n        if ($stream === false) {\n            throw new CakeException(sprintf('Cannot open resource `%s`', $file));\n        }\n\n        $stat = fstat($stream);\n\n        if ($stat === false || $stat['size'] < self::MO_HEADER_SIZE) {\n            throw new CakeException('Invalid format for MO translations file');\n        }\n        /** @var array $magic */\n        $magic = unpack('V1', (string)fread($stream, 4));\n        $magic = hexdec(substr(dechex(current($magic)), -8));\n\n        if ($magic === self::MO_LITTLE_ENDIAN_MAGIC) {\n            $isBigEndian = false;\n        } elseif ($magic === self::MO_BIG_ENDIAN_MAGIC) {\n            $isBigEndian = true;\n        } else {\n            throw new CakeException('Invalid format for MO translations file');\n        }\n\n        // offset formatRevision\n        fread($stream, 4);\n\n        $count = $this->_readLong($stream, $isBigEndian);\n        $offsetId = $this->_readLong($stream, $isBigEndian);","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/cakephp/cakephp/blob/1128eba9b09f1946df684811350e26f2cef68fac/src/I18n/Parser/MoFileParser.php#L52-L88","documentation":"After opening a .mo file, MoFileParser::parse() stats it and rejects it if fstat fails or the file is smaller than the 28-byte MO magic header (MO_HEADER_SIZE). This means the file exists but is too small/empty to be a valid GNU MO file. CakePHP throws the same message later when the magic number is wrong, so the file may be truncated or not a MO file at all.","triggerScenarios":"Calling parse() on an empty file, a partially written/truncated .mo, a file whose stat fails, or on a non-MO file smaller than MO_HEADER_SIZE.","commonSituations":"msgfmt run interrupted leaving a 0-byte .mo; git LFS/checkout artifacts; copying a .po where a .mo was expected; disk full during deployment truncating the file.","solutions":["Regenerate the .mo file with msgfmt (or cake i18n extract/compile pipeline) and verify size > 0","Confirm the file is actually a compiled .mo (file magic via `file translation.mo`) and not a .po or HTML error page","Re-upload/redeploy the translation file; verify integrity with checksum after transfer","Add a pre-check: filesize($path) >= 28 before parsing"],"exampleFix":"// before\n$entries = $parser->parse($path); // truncated .mo\n// after\nif (filesize($path) < 28) { // MoFileParser::MO_HEADER_SIZE\n    throw new RuntimeException(\"Truncated MO file: $path\");\n}\n$entries = $parser->parse($path);","handlingStrategy":"validation","validationCode":"$size = @filesize($path);\nif ($size === false || $size < 28) throw new RuntimeException(\"Truncated/invalid MO: $path\");","typeGuard":null,"tryCatchPattern":"try {\n    $entries = (new MoFileParser())->parse($path);\n} catch (\\Cake\\Core\\Exception\\CakeException $e) {\n    if ($e->getMessage() === 'Invalid format for MO translations file') {\n        $entries = [];\n    } else { throw $e; }\n}","preventionTips":["Verify .mo file sizes/checksums after build and deploy","Regenerate .mo files with msgfmt instead of copying possibly truncated artifacts","Avoid interrupting msgfmt/copy operations; write to temp then rename","Add a smoke test that parses every shipped .mo file"],"tags":["i18n","mo","corrupt-file","parser"],"backgroundTag":"file-read-failed","analyzedSha":"1128eba9b09f1946df684811350e26f2cef68fac","analyzedAt":"2026-09-12T12:07:00.388Z","contentChangedAt":"2026-09-12T12:07:00.388Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}