{"record":{"id":"fce7b137785a655d","repo":"passbolt/passbolt_api","slug":"invalid-request-message-validation-rules-are-missing","errorCode":null,"errorMessage":"Invalid request, message validation rules are missing.","messagePattern":"Invalid request, message validation rules are missing\\.","errorType":"http","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"src/Service/OpenPGP/MessageValidationService.php","lineNumber":88,"sourceCode":"     */\n    public static function getAsymmetricMessageRules(): array\n    {\n        return array_merge(self::getDefaultRules(), [\n            self::HAS_ASYMMETRIC_PACKET_RULE,\n            self::HAS_EXACTLY_ONE_RECIPIENT,\n        ]);\n    }\n\n    /**\n     * @param string $armoredMessage user provided data\n     * @param array|null $rules to override default rules\n     * @return array key information (see OpenPGPBackendInterface::getKeyInfo)\n     */\n    public static function parseAndValidateMessage(string $armoredMessage, ?array $rules = null): array\n    {\n        $rules = $rules ?? self::getDefaultRules();\n        if (!count($rules)) {\n            throw new InternalErrorException('Invalid request, message validation rules are missing.');\n        }\n\n        // Parsing check is mandatory and always done first\n        // We don't even try the other rules if this one fails\n        try {\n            $messageInfo = self::getMessageInfo($armoredMessage);\n        } catch (Exception $exception) {\n            throw new CustomValidationException(__('The public key could not be parsed.'), [\n                'data' => [\n                    self::IS_PARSABLE_ARMORED_MESSAGE_RULE => $exception->getMessage(),\n                ],\n            ]);\n        }\n\n        // Other rules are recommended but not mandatory\n        // As one may want to see what's inside the message info for debugging purpose\n        $validationErrors = [];\n        foreach ($rules as $ruleName) {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Service/OpenPGP/MessageValidationService.php#L70-L106","documentation":"MessageValidationService::parseAndValidateMessage validates an armored OpenPGP message against a set of rules (has-key-id, has-exactly-one-recipient, etc.). If the caller passes null rules AND the default rules resolve to an empty array, an InternalErrorException is thrown because running with zero validation rules is an invariant violation / misconfiguration.","triggerScenarios":"Calling parseAndValidateMessage() (or via the validation middleware __invoke) when getDefaultRules() returns an empty array — e.g. GPG server key configuration missing so required default rules (from passbolt.gpg config) are not generated.","commonSituations":"Misconfigured passbolt.php GPG key settings, environment where the server key fingerprint is not set, overridden rules arrays accidentally emptied by integrations.","solutions":["Verify passbolt.gpg configuration (server key fingerprint, keyring) so getDefaultRules() returns rules.","Pass an explicit non-empty $rules array when calling parseAndValidateMessage directly.","Run `ddev refresh` / healthcheck to confirm GPG setup is valid.","Check for custom code filtering out all default rules."],"exampleFix":"// before\nMessageValidationService::parseAndValidateMessage($armored, []);\n// after\nMessageValidationService::parseAndValidateMessage($armored, [MessageValidationService::IS_PARSABLE_ARMORED_MESSAGE_RULE]);","handlingStrategy":"validation","validationCode":"$rules = $rules ?? MessageValidationService::getDefaultRules();\nif (!count($rules)) { throw new LogicException('no rules configured'); }","typeGuard":null,"tryCatchPattern":"try { parseAndValidateMessage($msg, $rules); } catch (InternalErrorException $e) { /* fix GPG config */ }","preventionTips":["Keep passbolt.gpg server key config valid","Run healthcheck to verify GPG setup","Never pass empty rule arrays"],"tags":["openpgp","gpg","config","validation"],"backgroundTag":"missing-required-config","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}