PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Conditional is not an Expression CF Rule conditional

Error message

Conditional is not an Expression CF Rule conditional

What it means

Wizard\Expression::fromConditional() rebuilds an Expression wizard from an existing Conditional, and only CONDITION_EXPRESSION conditionals qualify - rules whose condition is a formula evaluated against each cell. Cell value, text, blanks and date rules use other condition types and are rejected up front.

Source

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

    public function getConditional(): Conditional
    {
        /** @var string[] */
        $expression = $this->adjustConditionsForCellReferences([$this->expression]);

        $conditional = new Conditional();
        $conditional->setConditionType(Conditional::CONDITION_EXPRESSION);
        $conditional->setConditions($expression);
        $conditional->setStyle($this->getStyle());
        $conditional->setStopIfTrue($this->getStopIfTrue());

        return $conditional;
    }

    public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface
    {
        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');
        }

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Check $conditional->getConditionType() === Conditional::CONDITION_EXPRESSION first
  2. Use Wizard::fromConditional() to dispatch to the correct wizard automatically
  3. Wrap batch loops with try/catch to skip non-expression rules
  4. Log the actual condition type when a rule is skipped

Example fix

// before
$wizard = Wizard\Expression::fromConditional($conditional); // throws unless type is expression

// after
use PhpOffice\PhpSpreadsheet\Style\Conditional;

if ($conditional->getConditionType() === Conditional::CONDITION_EXPRESSION) {
    $wizard = Wizard\Expression::fromConditional($conditional);
} else {
    $wizard = Wizard::fromConditional($conditional);
}
Defensive patterns

Strategy: type-guard

Validate before calling

use PhpOffice\PhpSpreadsheet\Style\Conditional;

if ($conditional->getConditionType() === Conditional::CONDITION_EXPRESSION) {
    $wizard = Wizard\Expression::fromConditional($conditional, $cellRange);
} else {
    $wizard = Wizard::fromConditional($conditional, $cellRange);
}

Type guard

function isExpressionConditional(Conditional $conditional): bool
{
    return $conditional->getConditionType() === Conditional::CONDITION_EXPRESSION;
}

Try / catch

use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;

try {
    $wizard = Wizard\Expression::fromConditional($conditional, $cellRange);
} catch (PhpSpreadsheetException $e) {
    $wizard = Wizard::fromConditional($conditional, $cellRange);
}

Prevention

When it happens

Trigger: Calling Expression::fromConditional() on a Conditional built by a CellValue, TextValue, Blanks or DateValue wizard; passing rules whose condition type is cellIs or timePeriod.

Common situations: Rule editors defaulting to the expression wizard; round-tripping imported rule sets without checking each rule's type; copy-pasted conversion code.

Related errors


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