PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Conditional is not an Errors CF Rule conditional

Error message

Conditional is not an Errors CF Rule conditional

What it means

Wizard\Errors::fromConditional() rebuilds an Errors wizard from an existing Conditional, but it only accepts the containsErrors and notContainsErrors condition types - the two a Blanks-style inverse wizard can round-trip. Other condition types (cellIs, expression, containsText, ...) are rejected up front.

Source

Thrown at src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/Errors.php:67

        $conditional = new Conditional();
        $conditional->setConditionType(
            $this->inverse ? Conditional::CONDITION_CONTAINSERRORS : Conditional::CONDITION_NOTCONTAINSERRORS
        );
        $conditional->setConditions([$this->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_CONTAINSERRORS
            && $conditional->getConditionType() !== Conditional::CONDITION_NOTCONTAINSERRORS
        ) {
            throw new Exception('Conditional is not an Errors CF Rule conditional');
        }

        $wizard = new self($cellRange);
        $wizard->style = $conditional->getStyle();
        $wizard->stopIfTrue = $conditional->getStopIfTrue();
        $wizard->inverse = $conditional->getConditionType() === Conditional::CONDITION_CONTAINSERRORS;

        return $wizard;
    }

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

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Check getConditionType() is CONDITION_CONTAINSERRORS or CONDITION_NOTCONTAINSERRORS before calling
  2. Use Wizard::fromConditional() for automatic dispatch
  3. If the rule is an ISERROR() expression, convert it with Wizard\Expression::fromConditional() instead
  4. Guard batch loops with try/catch

Example fix

// before
$wizard = Wizard\Errors::fromConditional($conditional); // throws unless containsErrors/notContainsErrors

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

if (in_array($conditional->getConditionType(),
    [Conditional::CONDITION_CONTAINSERRORS, Conditional::CONDITION_NOTCONTAINSERRORS], true)) {
    $wizard = Wizard\Errors::fromConditional($conditional);
} else {
    $wizard = Wizard::fromConditional($conditional);
}
Defensive patterns

Strategy: type-guard

Validate before calling

use PhpOffice\PhpSpreadsheet\Style\Conditional;

if (in_array($conditional->getConditionType(),
    [Conditional::CONDITION_CONTAINSERRORS, Conditional::CONDITION_NOTCONTAINSERRORS], true)) {
    $wizard = Wizard\Errors::fromConditional($conditional, $cellRange);
} else {
    $wizard = Wizard::fromConditional($conditional, $cellRange);
}

Type guard

function isErrorsConditional(Conditional $conditional): bool
{
    return in_array(
        $conditional->getConditionType(),
        [Conditional::CONDITION_CONTAINSERRORS, Conditional::CONDITION_NOTCONTAINSERRORS],
        true
    );
}

Try / catch

use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;

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

Prevention

When it happens

Trigger: Calling Errors::fromConditional() on a Conditional built by a CellValue or Expression wizard; passing an ISERROR(A1) rule stored as an expression rather than a true containsErrors rule; mixed-rule loops that force everything through the Errors factory.

Common situations: Error-highlighting rules written as expression formulas in imported files; generic rule conversion pipelines; rule editors that assume error checks are always containsErrors type.

Related errors


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