{"record":{"id":"c6c1bd11d241c25a","repo":"passbolt/passbolt_api","slug":"the-metadata-private-key-cleartext-data-should-not-be-empty","errorCode":null,"errorMessage":"The metadata private key cleartext data should not be empty.","messagePattern":"The metadata private key cleartext data should not be empty\\.","errorType":"http","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltCe/Metadata/src/Service/MetadataKeyShareDefaultService.php","lineNumber":178,"sourceCode":"    public function assertPrivateKey(string $clearText): void\n    {\n        if (empty($clearText)) {\n            $msg = __('The metadata private key should not be empty.');\n            throw new InternalErrorException($msg);\n        }\n\n        try {\n            $decoded = json_decode($clearText, true, 2, JSON_THROW_ON_ERROR);\n        } catch (Exception $exception) {\n            if (Configure::read('debug')) {\n                Log::error($clearText);\n            }\n            $msg = __('The metadata private key cleartext data should be in JSON format.');\n            throw new InternalErrorException($msg, 500, $exception);\n        }\n        if (!is_array($decoded) || empty($decoded)) {\n            $msg = __('The metadata private key cleartext data should not be empty.');\n            throw new InternalErrorException($msg);\n        }\n\n        $form = new MetadataCleartextPrivateKeyForm();\n        if (!$form->validate($decoded)) {\n            if (Configure::read('debug')) {\n                Log::error(json_encode($form->getErrors()));\n            }\n            $msg = __('The metadata private key cleartext data is not valid.');\n            throw new InternalErrorException($msg);\n        }\n    }\n\n    /**\n     * Get the OpenPGP Backend ready to decrypt with server key\n     *\n     * @param \\App\\Utility\\OpenPGP\\OpenPGPBackend $gpg for example OpenPGPBackendFactory::get()\n     * @param string|null $createdBy uuid of user\n     * @return \\App\\Utility\\OpenPGP\\OpenPGPBackend backend configured to use server keys","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Metadata/src/Service/MetadataKeyShareDefaultService.php#L160-L196","documentation":"assertPrivateKey throws InternalErrorException when the decoded JSON cleartext is not a non-empty array (null, scalar, or empty object/array). The data parsed as JSON but does not carry the expected key material structure.","triggerScenarios":"shareMetadataKeyWithUser path: decrypted cleartext decodes to JSON null (the string \"null\"), a scalar, or an empty object, so !is_array($decoded) || empty($decoded) triggers this InternalErrorException.","commonSituations":"Cleartext stored as the JSON literal \"null\" or \"[]\"; encoding bug that wrote an empty payload; partial write of the encrypted data during an interrupted operation.","solutions":["Inspect the stored record and re-import/re-create the metadata private key with the full JSON envelope","Check the code path that originally created the server copy for a bug that wrote an empty payload","Validate the cleartext with json_decode before encrypting it during import to catch empties early"],"exampleFix":"// before\n$ciphertext = $gpg->encrypt(json_encode($data) ?? '');\n// after\n$json = json_encode($data);\nif (!is_array(json_decode($json, true)) || empty(json_decode($json, true))) {\n    throw new \\InvalidArgumentException('Refusing to encrypt empty metadata private key cleartext');\n}\n$ciphertext = $gpg->encrypt($json, true);","handlingStrategy":"validation","validationCode":"$decoded = json_decode($cleartext, true, 2);\nif (!is_array($decoded) || $decoded === []) {\n    throw new \\DomainException('Decoded cleartext must be a non-empty array.');\n}","typeGuard":"function isNonEmptyArrayJson(string $cleartext): bool {\n    $d = json_decode($cleartext, true, 2);\n    return is_array($d) && count($d) > 0;\n}","tryCatchPattern":"try {\n    $service->shareMetadataKeysWithUser($uac, $userIds, $keyId);\n} catch (MetadataKeyShareException $e) {\n    if (str_contains($e->getMessage(), 'cleartext data should not be empty')) {\n        // stored payload decodes to null/empty: re-import or restore the key\n    }\n}","preventionTips":["Reject \"null\"/\"[]\" JSON payloads at import time, not just at share time","Ensure interrupted writes cannot truncate the encrypted payload (use transactions)","Run a data-integrity check over metadata_private_keys after bulk imports","Test share flows after any custom migration touching metadata private keys"],"tags":["openpgp","json","metadata-key","empty-data"],"backgroundTag":"empty-required-field","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}