{"record":{"id":"fbbfa0ee89b3ac82","repo":"PHPOffice/PhpSpreadsheet","slug":"invalid-grouping-for-column-autofilter-rule","errorCode":null,"errorMessage":"Invalid grouping for column AutoFilter Rule.","messagePattern":"Invalid grouping for column AutoFilter Rule\\.","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php","lineNumber":337,"sourceCode":"    public function getGrouping(): string\n    {\n        return $this->grouping;\n    }\n\n    /**\n     * Set AutoFilter Rule Grouping.\n     *\n     * @return $this\n     */\n    public function setGrouping(string $grouping): static\n    {\n        $this->setEvaluatedFalse();\n        if (\n            (!in_array($grouping, self::DATE_TIME_GROUPS))\n            && (!in_array($grouping, self::DYNAMIC_TYPES))\n            && (!in_array($grouping, self::TOP_TEN_TYPE))\n        ) {\n            throw new PhpSpreadsheetException('Invalid grouping for column AutoFilter Rule.');\n        }\n        $this->grouping = $grouping;\n\n        return $this;\n    }\n\n    /**\n     * Set AutoFilter Rule.\n     *\n     * @param string $operator see self::AUTOFILTER_COLUMN_RULE_*\n     * @param int|int[]|string|string[] $value\n     *\n     * @return $this\n     */\n    public function setRule(string $operator, $value, ?string $grouping = null): static\n    {\n        $this->setEvaluatedFalse();\n        $this->setOperator($operator);","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php#L319-L355","documentation":"Rule::setGrouping() accepts three disjoint sets: the date/time group names (year, month, day, hour, minute, second), the dynamic filter names (yesterday ... belowAverage, M1-M12, Q1-Q4), and the top-ten types ('top', 'bottom'). Any other string is rejected.","triggerScenarios":"->setGrouping('weekly'), ->setGrouping('Top') (case matters — the input is not lowercased) or ->setGrouping('quarter').","commonSituations":"Hand-written grouping strings with wrong casing or invented names; values copied from Excel UI labels ('Top 10') rather than the internal tokens.","solutions":["Use the Rule constants: AUTOFILTER_RULETYPE_DATEGROUP_* for date groups, AUTOFILTER_RULETYPE_DYNAMIC_* for dynamic filters, AUTOFILTER_COLUMN_RULE_TOPTEN_TOP/BOTTOM for top-ten","Note that setGrouping does not lowercase input — pass exact lowercase values when mapping from external data"],"exampleFix":"// before\n$rule->setGrouping('month of year');\n\n// after\n$rule->setGrouping(\\PhpOffice\\PhpSpreadsheet\\Worksheet\\AutoFilter\\Column\\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH);","handlingStrategy":"validation","validationCode":"use PhpOffice\\PhpSpreadsheet\\Worksheet\\AutoFilter\\Column\\Rule;\n$valid = array_merge(\n    ['year', 'month', 'day', 'hour', 'minute', 'second'], // date groups\n    ['top', 'bottom'], // top-ten types\n    array_map(fn ($c) => constant(Rule::class . '::' . $c), preg_grep('/^AUTOFILTER_RULETYPE_DYNAMIC_/', array_keys((new ReflectionClass(Rule::class))->getConstants())))\n);\nif (!in_array(strtolower($grouping), $valid, true)) {\n    throw new InvalidArgumentException(\"Unknown grouping '$grouping'\");\n}\n$rule->setGrouping(strtolower($grouping));","typeGuard":"function isValidRuleGrouping(string $grouping): bool\n{\n    static $valid;\n    $valid ??= array_merge(\n        ['year', 'month', 'day', 'hour', 'minute', 'second', 'top', 'bottom'],\n        array_values(array_filter(\n            array_map(fn ($v) => is_string($v) ? $v : null,\n                (new ReflectionClass(\\PhpOffice\\PhpSpreadsheet\\Worksheet\\AutoFilter\\Column\\Rule::class))->getConstants()),\n            fn ($v) => is_string($v) && preg_match('/^(yesterday|today|tomorrow|yearToDate|(this|last|next)(Year|Quarter|Month|Week)|M([1-9]|1[0-2])|Q[1-4]|aboveAverage|belowAverage)$/', $v)\n        ))\n    );\n\n    return in_array(strtolower($grouping), $valid, true);\n}","tryCatchPattern":"try {\n    $rule->setGrouping($grouping);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    $rule->setGrouping(Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH);\n}","preventionTips":["setGrouping is case-sensitive: normalize with strtolower() first","Pick grouping values from the Rule class constants, not Excel UI labels"],"tags":["autofilter","grouping","enum","validation","phpspreadsheet"],"backgroundTag":"invalid-enum-value","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}