{"record":{"id":"f845f1e1d630d3e3","repo":"PHPOffice/PhpSpreadsheet","slug":"we-should-not-be-expecting-a-condition","errorCode":null,"errorMessage":"We should not be expecting a condition","messagePattern":"We should not be expecting a condition","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Calculation\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Calculation/Engine/BranchPruner.php","lineNumber":168,"sourceCode":"            } elseif ($this->thenMap[$this->pendingStoreKey]) {\n                $this->thenMap[$this->pendingStoreKey] = false;\n                $this->elseMap[$this->pendingStoreKey] = true;\n            } elseif ($this->elseMap[$this->pendingStoreKey]) {\n                throw new Exception('Reaching fourth argument of an IF');\n            }\n        }\n    }\n\n    public function closingBrace(mixed $value): void\n    {\n        if (!empty($this->pendingStoreKey) && $this->braceDepthMap[$this->pendingStoreKey] === -1) {\n            // we are closing an IF(\n            if ($value !== 'IF(') {\n                throw new Exception('Parser bug we should be in an \"IF(\"');\n            }\n\n            if ($this->conditionMap[$this->pendingStoreKey]) {\n                throw new Exception('We should not be expecting a condition');\n            }\n\n            $this->thenMap[$this->pendingStoreKey] = false;\n            $this->elseMap[$this->pendingStoreKey] = false;\n            --$this->braceDepthMap[$this->pendingStoreKey];\n            array_pop($this->storeKeysStack);\n            $this->pendingStoreKey = null;\n        }\n    }\n\n    public function currentCondition(): ?string\n    {\n        return $this->currentCondition;\n    }\n\n    public function currentOnlyIf(): ?string\n    {\n        return $this->currentOnlyIf;","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Calculation/Engine/BranchPruner.php#L150-L186","documentation":"BranchPruner::closingBrace() runs when the parser closes an IF( whose state is still in the condition slot, meaning the IF has only one argument and no true/false branch; it then throws 'We should not be expecting a condition' and parsing aborts. Excel likewise requires at least two arguments for IF.","triggerScenarios":"Formulas like =IF(A1>0) or =IF(A1) (parentheses close right after the condition, no comma); nested cases such as =IF(IF(A1),2,3); truncated formula strings cut off before the branches.","commonSituations":"Formulas built by concatenation where the branches were never appended; optional-branch code that omits the else part entirely instead of writing a default; users editing a formula and deleting the branches; data-import pipelines that truncate long formula strings.","solutions":["Always supply at least condition plus true-branch: =IF(A1>0, 1, 0).","When building conditionals programmatically, default the missing pieces explicitly rather than omitting them.","Lint formula strings for IF( occurrences closed with no top-level comma before the matching ).","Catch PhpOffice\\PhpSpreadsheet\\Calculation\\Exception around calculation of untrusted formulas and report the cell."],"exampleFix":"// before - throws 'We should not be expecting a condition'\n$cell->setValue('=IF(A1>0)');\n\n// after\n$cell->setValue('=IF(A1>0, 1, 0)');","handlingStrategy":"try-catch","validationCode":"// An IF( with no top-level comma before its closing paren is incomplete.\nfunction ifMissingBranches(string $formula): bool\n{\n    return (bool) preg_match('/=\\s*IF\\([^,]*\\)/i', $formula);\n}","typeGuard":null,"tryCatchPattern":"use PhpOffice\\PhpSpreadsheet\\Calculation\\Exception as CalcException;\n\ntry {\n    $value = Calculation::getInstance($spreadsheet)->calculateFormula($formula);\n} catch (CalcException $e) {\n    // 'We should not be expecting a condition' -> IF() had only its condition\n    $value = '#ERROR';\n}","preventionTips":["Always emit IF(cond, trueValue, falseValue) - at minimum condition plus true-branch.","When conditionals are assembled from optional parts, substitute defaults instead of omitting arguments.","Validate imported formula strings for IF( closed without a comma."],"tags":["phpspreadsheet","formula-parser","if-function","branch-pruner","incomplete-formula"],"backgroundTag":"formula-parser-error","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}