{"record":{"id":"0ab458fce702cc14","repo":"PHPOffice/PhpSpreadsheet","slug":"no-wizard-exists-for-this-cf-rule-type","errorCode":null,"errorMessage":"No wizard exists for this CF rule type","messagePattern":"No wizard exists for this CF rule type","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard.php","lineNumber":47,"sourceCode":"    public function __construct(string $cellRange)\n    {\n        $this->cellRange = $cellRange;\n    }\n\n    public function newRule(string $ruleType): WizardInterface\n    {\n        return match ($ruleType) {\n            self::CELL_VALUE => new Wizard\\CellValue($this->cellRange),\n            self::TEXT_VALUE => new Wizard\\TextValue($this->cellRange),\n            self::BLANKS => new Wizard\\Blanks($this->cellRange, true),\n            self::NOT_BLANKS => new Wizard\\Blanks($this->cellRange, false),\n            self::ERRORS => new Wizard\\Errors($this->cellRange, true),\n            self::NOT_ERRORS => new Wizard\\Errors($this->cellRange, false),\n            self::EXPRESSION, self::FORMULA => new Wizard\\Expression($this->cellRange),\n            self::DATES_OCCURRING => new Wizard\\DateValue($this->cellRange),\n            self::DUPLICATES => new Wizard\\Duplicates($this->cellRange, false),\n            self::UNIQUE => new Wizard\\Duplicates($this->cellRange, true),\n            default => throw new Exception('No wizard exists for this CF rule type'),\n        };\n    }\n\n    public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface\n    {\n        $conditionalType = $conditional->getConditionType();\n\n        return match ($conditionalType) {\n            Conditional::CONDITION_CELLIS => Wizard\\CellValue::fromConditional($conditional, $cellRange),\n            Conditional::CONDITION_CONTAINSTEXT, Conditional::CONDITION_NOTCONTAINSTEXT, Conditional::CONDITION_BEGINSWITH, Conditional::CONDITION_ENDSWITH => Wizard\\TextValue::fromConditional($conditional, $cellRange),\n            Conditional::CONDITION_CONTAINSBLANKS, Conditional::CONDITION_NOTCONTAINSBLANKS => Wizard\\Blanks::fromConditional($conditional, $cellRange),\n            Conditional::CONDITION_CONTAINSERRORS, Conditional::CONDITION_NOTCONTAINSERRORS => Wizard\\Errors::fromConditional($conditional, $cellRange),\n            Conditional::CONDITION_TIMEPERIOD => Wizard\\DateValue::fromConditional($conditional, $cellRange),\n            Conditional::CONDITION_EXPRESSION => Wizard\\Expression::fromConditional($conditional, $cellRange),\n            Conditional::CONDITION_DUPLICATES, Conditional::CONDITION_UNIQUE => Wizard\\Duplicates::fromConditional($conditional, $cellRange),\n            default => throw new Exception('No wizard exists for this CF rule type'),\n        };\n    }","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard.php#L29-L65","documentation":"Wizard::newRule(string $ruleType) is a factory mapping a fixed set of rule-type identifiers to conditional-formatting wizard objects: Wizard::CELL_VALUE ('cellValue'), TEXT_VALUE ('textValue'), BLANKS/NOT_BLANKS, ERRORS/NOT_ERRORS, EXPRESSION/FORMULA, DATES_OCCURRING ('DateValue') and DUPLICATES/UNIQUE. The match expression has no wildcard arm, so any string that is not exactly one of those identifiers throws. Matching is case-sensitive, and the date wizard's identifier is the camel-cased 'DateValue', not 'datesOccurring'.","triggerScenarios":"Passing raw config/UI strings to newRule() without normalization ('Cell Value', 'cellvalue', 'cellIs'); reusing Conditional condition-type strings (e.g. 'cellIs', 'containsText') which are not Wizard identifiers; wrong casing for the date rule such as 'datevalue'.","commonSituations":"Mapping a YAML/JSON rule config, database column or form dropdown straight into newRule(); copying cfRule type values from xlsx XML into wizard calls; assuming every rule type a UI offers has a wizard.","solutions":["Always pass the Wizard class constants: (new Wizard($range))->newRule(Wizard::CELL_VALUE)","Validate dynamic strings against the list of Wizard::* rule-type constants before calling newRule()","If the input is a condition-type string or a Conditional object, use Wizard::fromConditional() which dispatches on condition type","Normalize config keys to exactly the Wizard constant values at load time"],"exampleFix":"// before\n$ruleType = $config['rule_type'];                  // e.g. 'Cell Value'\n$wizard = (new Wizard('A1:E10'))->newRule($ruleType); // throws\n\n// after\nuse PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\Wizard;\n\n$map = [\n    'cellValue' => Wizard::CELL_VALUE,\n    'textValue' => Wizard::TEXT_VALUE,\n    'blanks'    => Wizard::BLANKS,\n    'errors'    => Wizard::ERRORS,\n    'formula'   => Wizard::EXPRESSION,\n    'dates'     => Wizard::DATES_OCCURRING,\n    'duplicates'=> Wizard::DUPLICATES,\n];\n$ruleType = $map[$config['rule_type']] ?? Wizard::CELL_VALUE;\n$wizard = (new Wizard('A1:E10'))->newRule($ruleType);","handlingStrategy":"validation","validationCode":"use PhpOffice\\PhpSpreadsheet\\Style\\ConditionalFormatting\\Wizard;\n\n$validRuleTypes = [\n    Wizard::CELL_VALUE, Wizard::TEXT_VALUE, Wizard::BLANKS, Wizard::NOT_BLANKS,\n    Wizard::ERRORS, Wizard::NOT_ERRORS, Wizard::EXPRESSION, Wizard::FORMULA,\n    Wizard::DATES_OCCURRING, Wizard::DUPLICATES, Wizard::UNIQUE,\n];\nif (!in_array($ruleType, $validRuleTypes, true)) {\n    throw new InvalidArgumentException('Unsupported CF rule type: ' . $ruleType);\n}\n$wizard = (new Wizard($cellRange))->newRule($ruleType);","typeGuard":null,"tryCatchPattern":"use PhpOffice\\PhpSpreadsheet\\Exception as PhpSpreadsheetException;\n\ntry {\n    $wizard = (new Wizard($cellRange))->newRule($ruleType);\n} catch (PhpSpreadsheetException $e) {\n    // unknown rule type: fall back to a safe default or reject the input\n    throw new InvalidArgumentException('Unknown rule type: ' . $ruleType, 0, $e);\n}","preventionTips":["Always pass Wizard class constants instead of raw strings to newRule()","Map external config/UI values to Wizard constants through an explicit whitelist","Remember identifiers are case-sensitive and the date rule is 'DateValue'","If the input is a condition-type string, use Wizard::fromConditional() instead"],"tags":["php","phpspreadsheet","conditional-formatting","wizard","factory","invalid-argument"],"backgroundTag":"unsupported-rule-type","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}