PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
Conditional is not a Cell Value CF Rule conditional
Error message
Conditional is not a Cell Value CF Rule conditional
What it means
Wizard\CellValue::fromConditional() rebuilds a CellValue wizard from an existing Conditional, and only CONDITION_CELLIS conditionals qualify - those are the rules built from comparison operators (equal, greaterThan, between, ...). Text, expression, blanks, errors and date rules use different condition types and are rejected up front.
Solutions
- Check $conditional->getConditionType() === Conditional::CONDITION_CELLIS first
- Use Wizard::fromConditional() to dispatch to the correct wizard automatically
- For formula-style comparisons, use Wizard\Expression::fromConditional() instead
- Guard batch loops with try/catch to skip non-cellIs rules
Example fix
// before
$wizard = Wizard\CellValue::fromConditional($conditional); // throws unless type is cellIs
// after
use PhpOffice\PhpSpreadsheet\Style\Conditional;
if ($conditional->getConditionType() === Conditional::CONDITION_CELLIS) {
$wizard = Wizard\CellValue::fromConditional($conditional);
} else {
$wizard = Wizard::fromConditional($conditional); // dispatches on actual type
} Defensive patterns
Strategy: type-guard
Validate before calling
use PhpOffice\PhpSpreadsheet\Style\Conditional;
if ($conditional->getConditionType() === Conditional::CONDITION_CELLIS) {
$wizard = Wizard\CellValue::fromConditional($conditional, $cellRange);
} else {
$wizard = Wizard::fromConditional($conditional, $cellRange);
} Type guard
function isCellValueConditional(Conditional $conditional): bool
{
return $conditional->getConditionType() === Conditional::CONDITION_CELLIS;
} Try / catch
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
try {
$wizard = Wizard\CellValue::fromConditional($conditional, $cellRange);
} catch (PhpSpreadsheetException $e) {
$wizard = Wizard::fromConditional($conditional, $cellRange);
} Prevention
- Verify the condition type is cellIs before using the CellValue factory
- Use Wizard::fromConditional() when the rule's origin is unknown
- Treat formula-based comparisons as EXPRESSION rules
- Centralize type dispatch in one place instead of scattering per-class calls
When it happens
Trigger: Passing a Conditional whose getConditionType() is containsText, expression, timePeriod, containsBlanks, containsErrors, etc. to CellValue::fromConditional(); iterating mixed rules with a hard-coded CellValue factory call.
Common situations: Generic 'edit existing rule' UIs that pick the wrong wizard class; converting rules loaded from files where the condition type is unknown; copy-pasted conversion pipelines that never check the type.
Related errors
- AND Value is only appropriate for range operators
- Conditional is not a Blanks CF Rule conditional
- Conditional is not a Date Value CF Rule conditional
- Conditional is not a Duplicates CF Rule conditional
- Conditional is not a Text Value CF Rule conditional
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/24651122da540aa9.
Report an issue: GitHub.
Appendix: source
Thrown at src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/CellValue.php:123
$conditional->setStyle($this->getStyle());
$conditional->setStopIfTrue($this->getStopIfTrue());
return $conditional;
}
protected static function unwrapString(string $condition): string
{
if ((str_starts_with($condition, '"')) && (str_starts_with(strrev($condition), '"'))) {
$condition = substr($condition, 1, -1);
}
return str_replace('""', '"', $condition);
}
public static function fromConditional(Conditional $conditional, string $cellRange = 'A1'): WizardInterface
{
if ($conditional->getConditionType() !== Conditional::CONDITION_CELLIS) {
throw new Exception('Conditional is not a Cell Value CF Rule conditional');
}
$wizard = new self($cellRange);
$wizard->style = $conditional->getStyle();
$wizard->stopIfTrue = $conditional->getStopIfTrue();
$wizard->operator = $conditional->getOperatorType();
$conditions = $conditional->getConditions();
foreach ($conditions as $index => $condition) {
// Best-guess to try and identify if the text is a string literal, a cell reference or a formula?
$operandValueType = Wizard::VALUE_TYPE_LITERAL;
if (is_string($condition)) {
if (Calculation::keyInExcelConstants($condition)) {
$condition = Calculation::getExcelConstants($condition);
} elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '$/i', $condition)) {
$operandValueType = Wizard::VALUE_TYPE_CELL;
$condition = self::reverseAdjustCellRef($condition, $cellRange);
} elseif (View on GitHub (pinned to 65b080eef4)