PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Invalid Operation for Expression CF Rule Wizard

Error message

Invalid Operation for Expression CF Rule Wizard

What it means

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.

Source

Thrown at src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Expression.php:63

        if ($conditional->getConditionType() !== Conditional::CONDITION_EXPRESSION) {
            throw new Exception('Conditional is not an Expression CF Rule conditional');
        }

        $wizard = new self($cellRange);
        $wizard->style = $conditional->getStyle();
        $wizard->stopIfTrue = $conditional->getStopIfTrue();
        $wizard->expression = self::reverseAdjustCellRef((string) ($conditional->getConditions()[0]), $cellRange);

        return $wizard;
    }

    /**
     * @param string[] $arguments
     */
    public function __call(string $methodName, array $arguments): self
    {
        if ($methodName !== 'formula') {
            throw new Exception('Invalid Operation for Expression CF Rule Wizard');
        }

        $this->expression(...$arguments);

        return $this;
    }
}

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Call formula($expression) - or the real public method expression($expression)
  2. Validate dynamic method names against ['formula'] before invoking
  3. Catch PhpSpreadsheetException around dynamic calls
  4. Remember the expression is a raw Excel formula string, not a query-builder DSL

Example fix

// before
$expressionWizard = (new Wizard('A1:E10'))->newRule(Wizard::EXPRESSION);
$expressionWizard->where('A1>5');   // throws

// after
$expressionWizard->formula('A1>5'); // or ->expression('A1>5')
Defensive patterns

Strategy: validation

Validate before calling

$allowed = ['formula'];
$method = $config['method'] ?? 'formula';
if (!in_array($method, $allowed, true)) {
    throw new InvalidArgumentException('Unknown Expression wizard method: ' . $method);
}
$wizard->$method($expression);

Try / catch

use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;

try {
    $expressionWizard->formula($expr);
} catch (PhpSpreadsheetException $e) {
    throw new InvalidArgumentException('Invalid Expression wizard call', 0, $e);
}

Prevention

When it happens

Trigger: ->where('A1>5'); ->if(...); ->condition(...); any method name other than formula() (or the real expression() method).

Common situations: Developers expecting a Laravel/SQL query-builder-like API; code generators emitting guessed method names; dynamic fluent chains built from user input.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/3528797bed153932. Report an issue: GitHub.