{"record":{"id":"33d65c25a4026a37","repo":"passbolt/passbolt_api","slug":"0-is-not-a-valid-search-filter","errorCode":null,"errorMessage":"\"{0}\" is not a valid search filter.","messagePattern":"\"(.+?)\" is not a valid search filter\\.","errorType":"validation","errorClass":"CakeException","httpStatus":400,"severity":"error","filePath":"src/Controller/Component/QueryStringComponent.php","lineNumber":448,"sourceCode":"        return true;\n    }\n\n    /**\n     * Validate Search Filters\n     * Input must be a non-assoc array with utf8 char values between 3 and 64 char in length\n     * Example:\n     * - 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","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Component/QueryStringComponent.php#L430-L466","documentation":"Thrown by validateFilterSearch when a search filter entry has a non-integer array key. The search filter expects a numerically indexed list of keywords; keys like 'keywords' or '0x' indicate malformed structure.","triggerScenarios":"Passing an array with string keys to validateFilterSearch, e.g. ['keywords' => 'john'] instead of ['john'], typically from badly parsed query-string filter[search] input.","commonSituations":"Clients building filter[search][keyword]=x instead of filter[search][0]=x; framework query parsing turning numeric keys into associative ones; hand-constructed arrays in tests.","solutions":["Send search keywords as a numerically indexed list: filter[search][0]=john&filter[search][1]=doe","Server-side, call array_values($values) to reindex before validating if input shape is trusted","Use the correct single-value filter validator if a named filter was intended","Catch CakeException and return 400 describing the expected list format"],"exampleFix":"// before\nvalidateFilterSearch(['keyword' => 'john']);\n// after\nvalidateFilterSearch(array_values(['keyword' => 'john'])); // ['john']","handlingStrategy":"validation","validationCode":"$isShaped = array_is_list($values); if (!$isShaped) { /* reindex or reject */ }","typeGuard":"$isValid = is_array($values) && array_is_list($values);","tryCatchPattern":"try { validateFilterSearch($values); } catch (\\Cake\\Core\\Exception\\CakeException $e) { throw new BadRequestException($e->getMessage()); }","preventionTips":["Send search filters as filter[search][0]=... numbered lists, never named keys","Call array_values() on trusted arrays before validation","Add integration tests asserting the query-string shape clients actually send"],"tags":["php","cakephp","query-string","validation","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"}