passbolt/passbolt_api · error · CakeException

" " is not a valid group filter.

Error message

"{0}" is not a valid group filter.

What it means

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.

Solutions

  1. Use list syntax in the query string: filter[has-groups][]=<uuid> for each group id.
  2. Ensure the array passed to validateFilterGroups has sequential integer keys (use array_values($values) before validating).
  3. If calling the method directly, convert assoc input with array_values() or reject assoc input earlier with clearer messaging.

Example fix

// before
GET /resources?filter[has-groups][group]=98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08
// after
GET /resources?filter[has-groups][]=98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08
Defensive patterns

Strategy: validation

Validate before calling

if (!is_array($values)) { throw new \InvalidArgumentException('Filter must be an array.'); }
foreach (array_keys($values) as $k) {
    if (!is_int($k)) {
        throw new \InvalidArgumentException('Group filter keys must be integers; use filter[has-groups][]= syntax.');
    }
}

Type guard

function isIntKeyedList(mixed $values): bool {
    return is_array($values) && $values === array_values($values);
}

Try / catch

try {
    $ok = QueryStringComponent::validateFilterGroups($values, $filterName);
} catch (\Cake\Core\Exception\CakeException $e) {
    throw new BadRequestException($e->getMessage());
}

Prevention

When it happens

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

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

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/72aa4d77a3c2fd87. Report an issue: GitHub.

Appendix: source

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

        return true;
    }

    /**
     * Validate a filter that is an array of group id
     * Examples:
     * - Bueno: [0 => '98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08']
     * - No Bueno: ['this' => 'no']
     *
     * @param array $values array of group id to check
     * @param string $filterName for error message display
     * @throw CakeException if the filter is not valid
     * @return bool true if validate
     */
    public static function validateFilterGroups(array $values, string $filterName): bool
    {
        foreach ($values as $i => $groupId) {
            if (!is_int($i)) {
                throw new CakeException(__('"{0}" is not a valid group filter.', $i, $filterName));
            }
            if (!is_string($groupId) || empty($groupId)) {
                throw new CakeException(__('"{0}" is not a valid group filter.', $i));
            }
            self::validateFilterGroup($groupId, $filterName);
        }

        return true;
    }

    /**
     * Validate a filter that is an array of parent id
     * Examples:
     * - Bueno: [0 => '98c2bef5-cd5f-59e7-a1a7-0107c9a7cf08']
     * - No Bueno: ['this' => 'no']
     *
     * @param array $values array of group id to check
     * @param string|bool $filtername for error message display

View on GitHub (pinned to 31c1bbc10f)