{"record":{"id":"4b58606414c78744","repo":"passbolt/passbolt_api","slug":"0-is-not-a-valid-order","errorCode":null,"errorMessage":"\"{0}\" is not a valid order.","messagePattern":"\"(.+?)\" is not a valid order\\.","errorType":"validation","errorClass":"CakeException","httpStatus":400,"severity":"error","filePath":"src/Controller/Component/QueryStringComponent.php","lineNumber":676,"sourceCode":"\n        return true;\n    }\n\n    /**\n     * Validate order\n     *\n     * @param array|null $orders a list of order to validate like ['Groups.name ASC', 'Users.created']\n     * @param array|null $allowedQueryItems whitelist\n     * @return bool true if validate\n     * @throws \\Cake\\Core\\Exception\\CakeException if the group name does not validate\n     * @deprecated Use the ApiPaginationComponent\n     */\n    public static function validateOrders(?array $orders = null, ?array $allowedQueryItems = null): bool\n    {\n        if (isset($orders)) {\n            foreach ($orders as $orderName) {\n                if (!self::isOrder($orderName)) {\n                    throw new CakeException(__('\"{0}\" is not a valid order.', $orderName));\n                }\n                $order = explode(' ', $orderName); // remove ASC DESC if any\n                if (!isset($allowedQueryItems) || !in_array($order[0], $allowedQueryItems['order'])) {\n                    throw new CakeException(__('\"{0}\" is not in the list of allowed order.', $orderName));\n                }\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate Contain\n     *\n     * @param array|null $contain conditions\n     * @return bool true if validate\n     * @throws \\Cake\\Core\\Exception\\CakeException if the contain value is not 0 or 1\n     */","sourceCodeStart":658,"sourceCodeEnd":694,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Component/QueryStringComponent.php#L658-L694","documentation":"validateOrders checks each entry of the 'order' query-string parameter against the component's order grammar via isOrder(). It throws when an entry is not a syntactically valid order expression (field name optionally followed by ASC or DESC). This prevents arbitrary strings from being injected into ORM order clauses.","triggerScenarios":"GET requests with order values like ?order[]=foo-bar-baz, ?order[]=name ASCENDING, or containing characters outside the allowed pattern (field plus optional ' ASC'/' DESC').","commonSituations":"Clients inventing sort keywords ('ASCENDING', 'ascending') instead of the supported ASC/DESC; passing multiple space-separated directions; copying field paths with dots or slashes not supported by the grammar.","solutions":["Use the format '<field_name> ASC' or '<field_name> DESC' (or just '<field_name>').","Only use ASC or DESC as the direction keyword.","Check the controller's allowed order list and use one of its field names.","Remove any extra whitespace, commas, or multiple directions from the order value."],"exampleFix":"// before\nGET /users?order[]=full_name ASCENDING\n// after\nGET /users?order[]=full_name DESC","handlingStrategy":"validation","validationCode":"const ORDER_RE = /^[a-z_]+( (ASC|DESC))?$/i;\nif (!ORDER_RE.test(orderValue)) {\n  throw new Error(`Invalid order expression: ${orderValue}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use '<field> ASC' or '<field> DESC' order expressions","Limit direction keywords to ASC/DESC","Trim whitespace before building the query"],"tags":["query-string","sorting","validation"],"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"}