passbolt/passbolt_api · error · CakeException

" " is not a valid search filter. It is not a UTF8 string.

Error message

"{0}" is not a valid search filter. It is not a UTF8 string.

What it means

Thrown by validateFilterSearch when a keyword fails Cake's Validation::utf8() check — the search term contains bytes that are not valid UTF-8. The component rejects non-UTF-8 input early to protect downstream database queries.

Solutions

  1. Ensure the client sends UTF-8 encoded requests (Content-Type charset and URL percent-encoding in UTF-8)
  2. Server-side, detect/convert with mb_convert_encoding($keyword, 'UTF-8', 'ISO-8859-1') or reject via mb_check_encoding before validating
  3. Sanitize input with iconv('UTF-8', 'UTF-8//IGNORE', $keyword) to strip invalid bytes
  4. Catch CakeException and return 400 asking for UTF-8 encoded search terms

Example fix

// before
validateFilterSearch([$rawKeyword]);
// after
$keyword = mb_convert_encoding($rawKeyword, 'UTF-8', 'ISO-8859-1');
validateFilterSearch([$keyword]);
Defensive patterns

Strategy: validation

Validate before calling

foreach ($values as $k) { if (!mb_check_encoding((string)$k, 'UTF-8')) { /* reject or transcode */ } }

Type guard

$isUtf8 = fn(string $s): bool => mb_check_encoding($s, 'UTF-8');

Try / catch

try { validateFilterSearch($values); } catch (\Cake\Core\Exception\CakeException $e) { throw new BadRequestException($e->getMessage()); }

Prevention

When it happens

Trigger: A search keyword containing invalid byte sequences reaches validateFilterSearch, typically from improperly encoded URLs, latin-1 encoded clients, or binary data pasted into a search box.

Common situations: Legacy clients URL-encoding with ISO-8859-1; files/datasets in non-UTF-8 encodings feeding automated requests; corrupted form submissions missing charset declarations.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/Controller/Component/QueryStringComponent.php:455

     * - Bueno: [0 => 'ada', 1 => 'betty']
     * - No Bueno: ['this' => 'no']
     *
     * @param array $values query items
     * @throw CakeException if the filter is not valid
     * @return bool true if the filter is valid
     */
    public static function validateFilterSearch(array $values): bool
    {
        foreach ($values as $i => $keyword) {
            if (!is_int($i)) {
                throw new CakeException(__('"{0}" is not a valid search filter.', $i));
            }
            if (!is_scalar($keyword) || empty($keyword)) {
                throw new CakeException(__('"{0}" is not a valid search filter.', $i));
            }
            if (!Validation::utf8($keyword)) {
                $msg = __('"{0}" is not a valid search filter. It is not a UTF8 string.', $keyword);
                throw new CakeException($msg);
            }
            if (!Validation::lengthBetween($keyword, 1, 64)) {
                $msg = __('"{0}" is not a valid search filter.', $keyword) . ' ';
                $msg .= __('It should be between 1 and 64 char in length.');
                throw new CakeException($msg);
            }
        }

        return true;
    }

    /**
     * Validate Users Filters
     * Input must be a non-assoc array with utf8 char values between 3 and 64 char in length
     * Examples:
     * - Bueno: [0 => '98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08']
     * - No Bueno: ['this' => 'no']
     *

View on GitHub (pinned to 31c1bbc10f)