passbolt/passbolt_api · error · InternalErrorException

The metadata private key cleartext data should not be empty.

Error message

The metadata private key cleartext data should not be empty.

What it means

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.

Solutions

  1. Inspect the stored record and re-import/re-create the metadata private key with the full JSON envelope
  2. Check the code path that originally created the server copy for a bug that wrote an empty payload
  3. Validate the cleartext with json_decode before encrypting it during import to catch empties early

Example fix

// before
$ciphertext = $gpg->encrypt(json_encode($data) ?? '');
// after
$json = json_encode($data);
if (!is_array(json_decode($json, true)) || empty(json_decode($json, true))) {
    throw new \InvalidArgumentException('Refusing to encrypt empty metadata private key cleartext');
}
$ciphertext = $gpg->encrypt($json, true);
Defensive patterns

Strategy: validation

Validate before calling

$decoded = json_decode($cleartext, true, 2);
if (!is_array($decoded) || $decoded === []) {
    throw new \DomainException('Decoded cleartext must be a non-empty array.');
}

Type guard

function isNonEmptyArrayJson(string $cleartext): bool {
    $d = json_decode($cleartext, true, 2);
    return is_array($d) && count($d) > 0;
}

Try / catch

try {
    $service->shareMetadataKeysWithUser($uac, $userIds, $keyId);
} catch (MetadataKeyShareException $e) {
    if (str_contains($e->getMessage(), 'cleartext data should not be empty')) {
        // stored payload decodes to null/empty: re-import or restore the key
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/c6c1bd11d241c25a. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/Metadata/src/Service/MetadataKeyShareDefaultService.php:178

    public function assertPrivateKey(string $clearText): void
    {
        if (empty($clearText)) {
            $msg = __('The metadata private key should not be empty.');
            throw new InternalErrorException($msg);
        }

        try {
            $decoded = json_decode($clearText, true, 2, JSON_THROW_ON_ERROR);
        } catch (Exception $exception) {
            if (Configure::read('debug')) {
                Log::error($clearText);
            }
            $msg = __('The metadata private key cleartext data should be in JSON format.');
            throw new InternalErrorException($msg, 500, $exception);
        }
        if (!is_array($decoded) || empty($decoded)) {
            $msg = __('The metadata private key cleartext data should not be empty.');
            throw new InternalErrorException($msg);
        }

        $form = new MetadataCleartextPrivateKeyForm();
        if (!$form->validate($decoded)) {
            if (Configure::read('debug')) {
                Log::error(json_encode($form->getErrors()));
            }
            $msg = __('The metadata private key cleartext data is not valid.');
            throw new InternalErrorException($msg);
        }
    }

    /**
     * Get the OpenPGP Backend ready to decrypt with server key
     *
     * @param \App\Utility\OpenPGP\OpenPGPBackend $gpg for example OpenPGPBackendFactory::get()
     * @param string|null $createdBy uuid of user
     * @return \App\Utility\OpenPGP\OpenPGPBackend backend configured to use server keys

View on GitHub (pinned to 31c1bbc10f)