{"record":{"id":"0b38739c2cc83ea5","repo":"PHPOffice/PhpSpreadsheet","slug":"invalid-operation-for-duplicates-cf-rule-wizard","errorCode":null,"errorMessage":"Invalid Operation for Duplicates CF Rule Wizard","messagePattern":"Invalid Operation for Duplicates CF Rule Wizard","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Duplicates.php","lineNumber":67,"sourceCode":"        ) {\n            throw new Exception('Conditional is not a Duplicates CF Rule conditional');\n        }\n\n        $wizard = new self($cellRange);\n        $wizard->style = $conditional->getStyle();\n        $wizard->stopIfTrue = $conditional->getStopIfTrue();\n        $wizard->inverse = $conditional->getConditionType() === Conditional::CONDITION_UNIQUE;\n\n        return $wizard;\n    }\n\n    /**\n     * @param mixed[] $arguments\n     */\n    public function __call(string $methodName, array $arguments): self\n    {\n        if (!array_key_exists($methodName, self::OPERATORS)) {\n            throw new Exception('Invalid Operation for Duplicates CF Rule Wizard');\n        }\n\n        $this->inverse(self::OPERATORS[$methodName]);\n\n        return $this;\n    }\n}\n","sourceCodeStart":49,"sourceCodeEnd":75,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Duplicates.php#L49-L75","documentation":"The Duplicates wizard accepts exactly two magic methods from its OPERATORS map: duplicates() (highlight duplicate values) and unique() (highlight unique values). __call rejects every other method name with this exception, so there is no third mode to invoke.","triggerScenarios":"->distinct(); ->repeated(); ->uniqueValues(); any method name other than duplicates() or unique().","commonSituations":"SQL naming habits (DISTINCT) carried into the fluent API; guessing symmetric method names; dynamic invocation from configuration or user input.","solutions":["Use duplicates() or unique() only","Validate dynamic method names against ['duplicates', 'unique'] before invoking","Catch PhpSpreadsheetException around dynamic calls","Remember the inverse mode is chosen at construction too: (new Wizard($range))->newRule(Wizard::UNIQUE)"],"exampleFix":"// before\n$duplicatesWizard = (new Wizard('A1:E10'))->newRule(Wizard::DUPLICATES);\n$duplicatesWizard->distinct();   // throws\n\n// after\n$duplicatesWizard->duplicates(); // or ->unique()","handlingStrategy":"validation","validationCode":"$allowed = ['duplicates', 'unique'];\n$method = $config['mode'];\nif (!in_array($method, $allowed, true)) {\n    throw new InvalidArgumentException('Unknown Duplicates mode: ' . $method);\n}\n$wizard->$method();","typeGuard":null,"tryCatchPattern":"use PhpOffice\\PhpSpreadsheet\\Exception as PhpSpreadsheetException;\n\ntry {\n    $wizard->$method();\n} catch (PhpSpreadsheetException $e) {\n    throw new InvalidArgumentException('Invalid Duplicates mode: ' . $method, 0, $e);\n}","preventionTips":["Only duplicates() and unique() exist on this wizard","Do not guess SQL-style names like distinct()","Choose the mode at construction as well: newRule(Wizard::DUPLICATES) vs newRule(Wizard::UNIQUE)","Whitelist mode strings that arrive from config or user input"],"tags":["php","phpspreadsheet","conditional-formatting","wizard","duplicates","magic-methods"],"backgroundTag":"invalid-fluent-builder-method","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}