{"record":{"id":"5aad983c9c70b922","repo":"passbolt/passbolt_api","slug":"0-is-not-a-valid-search-filter-it-is-not-a-utf8-string","errorCode":null,"errorMessage":"\"{0}\" is not a valid search filter. It is not a UTF8 string.","messagePattern":"\"(.+?)\" is not a valid search filter\\. It is not a UTF8 string\\.","errorType":"validation","errorClass":"CakeException","httpStatus":400,"severity":"error","filePath":"src/Controller/Component/QueryStringComponent.php","lineNumber":455,"sourceCode":"     * - Bueno: [0 => 'ada', 1 => 'betty']\n     * - No Bueno: ['this' => 'no']\n     *\n     * @param array $values query items\n     * @throw CakeException if the filter is not valid\n     * @return bool true if the filter is valid\n     */\n    public static function validateFilterSearch(array $values): bool\n    {\n        foreach ($values as $i => $keyword) {\n            if (!is_int($i)) {\n                throw new CakeException(__('\"{0}\" is not a valid search filter.', $i));\n            }\n            if (!is_scalar($keyword) || empty($keyword)) {\n                throw new CakeException(__('\"{0}\" is not a valid search filter.', $i));\n            }\n            if (!Validation::utf8($keyword)) {\n                $msg = __('\"{0}\" is not a valid search filter. It is not a UTF8 string.', $keyword);\n                throw new CakeException($msg);\n            }\n            if (!Validation::lengthBetween($keyword, 1, 64)) {\n                $msg = __('\"{0}\" is not a valid search filter.', $keyword) . ' ';\n                $msg .= __('It should be between 1 and 64 char in length.');\n                throw new CakeException($msg);\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate Users Filters\n     * Input must be a non-assoc array with utf8 char values between 3 and 64 char in length\n     * Examples:\n     * - Bueno: [0 => '98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08']\n     * - No Bueno: ['this' => 'no']\n     *","sourceCodeStart":437,"sourceCodeEnd":473,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Component/QueryStringComponent.php#L437-L473","documentation":"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.","triggerScenarios":"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.","commonSituations":"Legacy clients URL-encoding with ISO-8859-1; files/datasets in non-UTF-8 encodings feeding automated requests; corrupted form submissions missing charset declarations.","solutions":["Ensure the client sends UTF-8 encoded requests (Content-Type charset and URL percent-encoding in UTF-8)","Server-side, detect/convert with mb_convert_encoding($keyword, 'UTF-8', 'ISO-8859-1') or reject via mb_check_encoding before validating","Sanitize input with iconv('UTF-8', 'UTF-8//IGNORE', $keyword) to strip invalid bytes","Catch CakeException and return 400 asking for UTF-8 encoded search terms"],"exampleFix":"// before\nvalidateFilterSearch([$rawKeyword]);\n// after\n$keyword = mb_convert_encoding($rawKeyword, 'UTF-8', 'ISO-8859-1');\nvalidateFilterSearch([$keyword]);","handlingStrategy":"validation","validationCode":"foreach ($values as $k) { if (!mb_check_encoding((string)$k, 'UTF-8')) { /* reject or transcode */ } }","typeGuard":"$isUtf8 = fn(string $s): bool => mb_check_encoding($s, 'UTF-8');","tryCatchPattern":"try { validateFilterSearch($values); } catch (\\Cake\\Core\\Exception\\CakeException $e) { throw new BadRequestException($e->getMessage()); }","preventionTips":["Declare UTF-8 charset on all client requests and forms","Transcode known legacy encodings (ISO-8859-1) at the edge","Run iconv('UTF-8','UTF-8//IGNORE') to sanitize third-party input"],"tags":["php","cakephp","validation","encoding","utf8","search"],"backgroundTag":"invalid-argument-format","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"}