{"record":{"id":"3528797bed153932","repo":"PHPOffice/PhpSpreadsheet","slug":"invalid-operation-for-expression-cf-rule-wizard","errorCode":null,"errorMessage":"Invalid Operation for Expression CF Rule Wizard","messagePattern":"Invalid Operation for Expression CF Rule Wizard","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Expression.php","lineNumber":63,"sourceCode":"        if ($conditional->getConditionType() !== Conditional::CONDITION_EXPRESSION) {\n            throw new Exception('Conditional is not an Expression CF Rule conditional');\n        }\n\n        $wizard = new self($cellRange);\n        $wizard->style = $conditional->getStyle();\n        $wizard->stopIfTrue = $conditional->getStopIfTrue();\n        $wizard->expression = self::reverseAdjustCellRef((string) ($conditional->getConditions()[0]), $cellRange);\n\n        return $wizard;\n    }\n\n    /**\n     * @param string[] $arguments\n     */\n    public function __call(string $methodName, array $arguments): self\n    {\n        if ($methodName !== 'formula') {\n            throw new Exception('Invalid Operation for Expression CF Rule Wizard');\n        }\n\n        $this->expression(...$arguments);\n\n        return $this;\n    }\n}\n","sourceCodeStart":45,"sourceCodeEnd":71,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Expression.php#L45-L71","documentation":"The Expression wizard's fluent surface is a single magic method, formula(), intercepted by __call; every other name throws. (expression() also works but as a real public method, not via magic.) Names borrowed from query-builder habits - where(), if(), condition() - are rejected because the wizard only wraps one formula string.","triggerScenarios":"->where('A1>5'); ->if(...); ->condition(...); any method name other than formula() (or the real expression() method).","commonSituations":"Developers expecting a Laravel/SQL query-builder-like API; code generators emitting guessed method names; dynamic fluent chains built from user input.","solutions":["Call formula($expression) - or the real public method expression($expression)","Validate dynamic method names against ['formula'] before invoking","Catch PhpSpreadsheetException around dynamic calls","Remember the expression is a raw Excel formula string, not a query-builder DSL"],"exampleFix":"// before\n$expressionWizard = (new Wizard('A1:E10'))->newRule(Wizard::EXPRESSION);\n$expressionWizard->where('A1>5');   // throws\n\n// after\n$expressionWizard->formula('A1>5'); // or ->expression('A1>5')","handlingStrategy":"validation","validationCode":"$allowed = ['formula'];\n$method = $config['method'] ?? 'formula';\nif (!in_array($method, $allowed, true)) {\n    throw new InvalidArgumentException('Unknown Expression wizard method: ' . $method);\n}\n$wizard->$method($expression);","typeGuard":null,"tryCatchPattern":"use PhpOffice\\PhpSpreadsheet\\Exception as PhpSpreadsheetException;\n\ntry {\n    $expressionWizard->formula($expr);\n} catch (PhpSpreadsheetException $e) {\n    throw new InvalidArgumentException('Invalid Expression wizard call', 0, $e);\n}","preventionTips":["Only formula() is magic; expression() is the real public method and also works","Do not use query-builder names like where() or if()","Pass the full Excel formula string in one call","Whitelist method names when they come from dynamic sources"],"tags":["php","phpspreadsheet","conditional-formatting","wizard","expression","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"}