{"record":{"id":"72aa4d77a3c2fd87","repo":"passbolt/passbolt_api","slug":"0-is-not-a-valid-group-filter","errorCode":null,"errorMessage":"\"{0}\" is not a valid group filter.","messagePattern":"\"(.+?)\" is not a valid group filter\\.","errorType":"validation","errorClass":"CakeException","httpStatus":400,"severity":"error","filePath":"src/Controller/Component/QueryStringComponent.php","lineNumber":511,"sourceCode":"        return true;\n    }\n\n    /**\n     * Validate a filter that is an array of group id\n     * Examples:\n     * - Bueno: [0 => '98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08']\n     * - No Bueno: ['this' => 'no']\n     *\n     * @param array $values array of group id to check\n     * @param string $filterName for error message display\n     * @throw CakeException if the filter is not valid\n     * @return bool true if validate\n     */\n    public static function validateFilterGroups(array $values, string $filterName): bool\n    {\n        foreach ($values as $i => $groupId) {\n            if (!is_int($i)) {\n                throw new CakeException(__('\"{0}\" is not a valid group filter.', $i, $filterName));\n            }\n            if (!is_string($groupId) || empty($groupId)) {\n                throw new CakeException(__('\"{0}\" is not a valid group filter.', $i));\n            }\n            self::validateFilterGroup($groupId, $filterName);\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate a filter that is an array of parent id\n     * Examples:\n     * - Bueno: [0 => '98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08']\n     * - No Bueno: ['this' => 'no']\n     *\n     * @param array $values array of group id to check\n     * @param string|bool $filtername for error message display","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Component/QueryStringComponent.php#L493-L529","documentation":"Thrown by QueryStringComponent::validateFilterGroups when the key of an entry in a group-id filter array is not an integer, i.e. the array was given as an associative array. Group filters must be non-assoc, numerically indexed lists of group ids. The message interpolates the offending array key, which is why it may show something like 'this' rather than the value.","triggerScenarios":"Passing an associative array such as ['this' => 'no'] (or ['group' => $id]) into validateFilterGroups, e.g. via a query string like ?filter[has-groups][group]=<id> instead of ?filter[has-groups][]=<id>.","commonSituations":"Client builds the filter as a key/value map instead of a list; URL query syntax uses filter[name][key]=value instead of filter[name][]=value; refactored code reuses an assoc options array directly.","solutions":["Use list syntax in the query string: filter[has-groups][]=<uuid> for each group id.","Ensure the array passed to validateFilterGroups has sequential integer keys (use array_values($values) before validating).","If calling the method directly, convert assoc input with array_values() or reject assoc input earlier with clearer messaging."],"exampleFix":"// before\nGET /resources?filter[has-groups][group]=98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08\n// after\nGET /resources?filter[has-groups][]=98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08","handlingStrategy":"validation","validationCode":"if (!is_array($values)) { throw new \\InvalidArgumentException('Filter must be an array.'); }\nforeach (array_keys($values) as $k) {\n    if (!is_int($k)) {\n        throw new \\InvalidArgumentException('Group filter keys must be integers; use filter[has-groups][]= syntax.');\n    }\n}","typeGuard":"function isIntKeyedList(mixed $values): bool {\n    return is_array($values) && $values === array_values($values);\n}","tryCatchPattern":"try {\n    $ok = QueryStringComponent::validateFilterGroups($values, $filterName);\n} catch (\\Cake\\Core\\Exception\\CakeException $e) {\n    throw new BadRequestException($e->getMessage());\n}","preventionTips":["Use []= (list) query-string syntax, never named keys, for multi-value filters.","Normalize input with array_values() before passing filter arrays around.","Unit-test filter builders with assoc input to catch shape regressions."],"tags":["validation","query-string","filter","array-shape"],"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"}