PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
Conditional is not a Text Value CF Rule conditional
Error message
Conditional is not a Text Value CF Rule conditional
What it means
Wizard\TextValue::fromConditional() rebuilds a TextValue wizard from an existing Conditional, but only for the four text condition types in its OPERATORS map: containsText, notContainsText, beginsWith and endsWith. Other condition types - including blanks and expression rules that test text - are rejected up front.
Source
Thrown at src/PhpSpreadsheet/Style/ConditionalFormatting/Wizard/TextValue.php:115
$conditional = new Conditional();
$conditional->setConditionType(self::OPERATORS[$this->operator]);
$conditional->setOperatorType($this->operator);
$conditional->setText(
$this->operandValueType !== Wizard::VALUE_TYPE_LITERAL
? $this->cellConditionCheck($this->operand)
: $this->operand
);
$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 (!in_array($conditional->getConditionType(), self::OPERATORS, true)) {
throw new Exception('Conditional is not a Text Value CF Rule conditional');
}
$wizard = new self($cellRange);
$wizard->operator = (string) array_search($conditional->getConditionType(), self::OPERATORS, true);
$wizard->style = $conditional->getStyle();
$wizard->stopIfTrue = $conditional->getStopIfTrue();
// Best-guess to try and identify if the text is a string literal, a cell reference or a formula?
$wizard->operandValueType = Wizard::VALUE_TYPE_LITERAL;
$condition = $conditional->getText();
if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '$/i', $condition)) {
$wizard->operandValueType = Wizard::VALUE_TYPE_CELL;
$condition = self::reverseAdjustCellRef($condition, $cellRange);
} elseif (
preg_match('/\(\)/', $condition)
|| preg_match('/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/i', $condition)
) {
$wizard->operandValueType = Wizard::VALUE_TYPE_FORMULA;View on GitHub (pinned to 65b080eef4)
Solutions
- Check getConditionType() is one of containsText, notContainsText, beginsWith, endsWith before calling
- Use Wizard::fromConditional() for automatic dispatch
- If the rule is an expression-based text test, convert it with Wizard\Expression::fromConditional() instead
- Guard batch loops with try/catch
Example fix
// before
$wizard = Wizard\TextValue::fromConditional($conditional); // throws unless text type
// after
use PhpOffice\PhpSpreadsheet\Style\Conditional;
if (in_array($conditional->getConditionType(), [
Conditional::CONDITION_CONTAINSTEXT, Conditional::CONDITION_NOTCONTAINSTEXT,
Conditional::CONDITION_BEGINSWITH, Conditional::CONDITION_ENDSWITH,
], true)) {
$wizard = Wizard\TextValue::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_CONTAINSTEXT, Conditional::CONDITION_NOTCONTAINSTEXT,
Conditional::CONDITION_BEGINSWITH, Conditional::CONDITION_ENDSWITH,
], true)) {
$wizard = Wizard\TextValue::fromConditional($conditional, $cellRange);
} else {
$wizard = Wizard::fromConditional($conditional, $cellRange);
} Type guard
function isTextValueConditional(Conditional $conditional): bool
{
return in_array($conditional->getConditionType(), [
Conditional::CONDITION_CONTAINSTEXT,
Conditional::CONDITION_NOTCONTAINSTEXT,
Conditional::CONDITION_BEGINSWITH,
Conditional::CONDITION_ENDSWITH,
], true);
} Try / catch
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
try {
$wizard = Wizard\TextValue::fromConditional($conditional, $cellRange);
} catch (PhpSpreadsheetException $e) {
$wizard = Wizard::fromConditional($conditional, $cellRange);
} Prevention
- Check the condition type is one of the four text types before calling the TextValue factory
- SEARCH()-based text checks stored as formulas are EXPRESSION rules
- Use the generic Wizard::fromConditional() for mixed or imported rule sets
- Remember the text operand lives in getText(), not in getConditions()
When it happens
Trigger: Calling TextValue::fromConditional() on a Conditional whose type is containsBlanks, expression, cellIs or timePeriod; passing a SEARCH()-based expression rule that behaves like 'contains' but was saved as CONDITION_EXPRESSION.
Common situations: Text filters implemented as expression formulas in imported files; generic rule editors assuming any text-related rule is a TextValue rule; mixed-rule conversion loops.
Related errors
- Conditional is not a Blanks CF Rule conditional
- Conditional is not a Cell Value CF Rule conditional
- Conditional is not a Date Value CF Rule conditional
- Conditional is not a Duplicates CF Rule conditional
- Conditional is not an Errors CF Rule conditional
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/dafbbf32b60b9406.
Report an issue: GitHub.