{"record":{"id":"731ebf29ef8e6d9c","repo":"passbolt/passbolt_api","slug":"0-is-not-a-valid-datetime-for-filter-1","errorCode":null,"errorMessage":"\"{0}\" is not a valid datetime for filter {1}.","messagePattern":"\"(.+?)\" is not a valid datetime for filter (.+?)\\.","errorType":"validation","errorClass":"CakeException","httpStatus":400,"severity":"error","filePath":"src/Controller/Component/QueryStringComponent.php","lineNumber":651,"sourceCode":"                __('\"{0}\" is not a valid timestamp for filter {1}.', $timestamp, $filterName)\n            );\n        }\n\n        return true;\n    }\n\n    /**\n     * Validate a filter that is a datetime.\n     *\n     * @param mixed $values the value to check\n     * @param string $filterName for error message display\n     * @throw CakeException if the filter is not valid\n     * @return bool if validate\n     */\n    public static function validateFilterDateTime(mixed $values, string $filterName): bool\n    {\n        if (!is_string($values)) {\n            throw new CakeException(__('\"{0}\" is not a valid datetime for filter {1}.', $values, $filterName));\n        }\n        try {\n            new DateTime($values);\n        } catch (Exception $e) {\n            throw new CakeException(__('\"{0}\" is not a valid datetime for filter {1}.', $values, $filterName));\n        }\n\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","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Controller/Component/QueryStringComponent.php#L633-L669","documentation":"validateFilterDateTime validates datetime filters by first ensuring the value is a string, then attempting to construct a PHP DateTime from it. This throw is raised when the value passed to a datetime filter is not a string at all (e.g. an array or nested value from the query string).","triggerScenarios":"Sending a filter value that PHP parses as a non-scalar (e.g. filter[]=modified-before>foo[] producing an array), so is_string() fails before DateTime parsing is attempted.","commonSituations":"Malformed query strings where the same filter key repeats or brackets in the value cause PHP to coerce the value to an array; automated clients posting JSON-ish syntax into query strings.","solutions":["Inspect the raw query string and ensure each filter value is a single scalar string.","Remove duplicate bracketed values that PHP turns into arrays (e.g. filter[]=x[]).","URL-encode the datetime value properly so it stays a single string.","Send an unambiguous datetime string such as '2024-01-01T00:00:00+00:00' that DateTime can parse."],"exampleFix":"// before\nGET /resources?filter[]=modified-before>2024-01-01 00:00:00[]\n// after\nGET /resources?filter[]=modified-before>2024-01-01T00:00:00%2B00:00","handlingStrategy":"validation","validationCode":"if (typeof filterValue !== 'string' || Array.isArray(filterValue)) {\n  throw new Error('Datetime filter value must be a single scalar string');\n}","typeGuard":"function isString(v: unknown): v is string {\n  return typeof v === 'string';\n}","tryCatchPattern":null,"preventionTips":["URL-encode filter values so PHP does not coerce them to arrays","Avoid duplicate/bracketed keys in the query string","Sanitize query building code to emit scalar values only"],"tags":["query-string","validation","datetime"],"backgroundTag":"invalid-date-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"}