PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Calculation\Exception
Token with id $id does not exist.
Error message
Token with id $id does not exist.
What it means
FormulaParser::getToken(int $id) indexes the token list built by parseToTokens(); an out-of-range id throws Calculation\Exception with 'Token with id $id does not exist.' An empty or whitespace-only formula yields zero tokens, so even getToken(0) with the default id can throw. The exception is a plain PHP exception, not an Excel error value.
Source
Thrown at src/PhpSpreadsheet/Calculation/FormulaParser.php:99
* Get Formula.
*/
public function getFormula(): string
{
return $this->formula;
}
/**
* Get Token.
*
* @param int $id Token id
*/
public function getToken(int $id = 0): FormulaToken
{
if (isset($this->tokens[$id])) {
return $this->tokens[$id];
}
throw new Exception("Token with id $id does not exist.");
}
/**
* Get Token count.
*/
public function getTokenCount(): int
{
return count($this->tokens);
}
/**
* Get Tokens.
*
* @return FormulaToken[]
*/
public function getTokens(): array
{
return $this->tokens;View on GitHub (pinned to 65b080eef4)
Solutions
- Bound the loop with $i < $parser->getTokenCount()
- Iterate getTokens() directly instead of indexing by id
- Early-return when getTokenCount() === 0
- Recompute indexes whenever the parsed formula changes
Example fix
// before
for ($i = 0; $i <= $parser->getTokenCount(); $i++) { // off-by-one: last id does not exist
process($parser->getToken($i));
}
// after
$count = $parser->getTokenCount();
for ($i = 0; $i < $count; $i++) {
process($parser->getToken($i));
} Defensive patterns
Strategy: validation
Validate before calling
$count = $parser->getTokenCount();
if ($count === 0) {
return; // nothing to walk
}
for ($i = 0; $i < $count; $i++) {
$token = $parser->getToken($i);
} Type guard
function tokenExists(FormulaParser $parser, int $id): bool
{
return $id >= 0 && $id < $parser->getTokenCount();
} Try / catch
try {
$token = $parser->getToken($id);
} catch (\PhpOffice\PhpSpreadsheet\Calculation\Exception $e) {
// 'Token with id N does not exist.' - fix the index bound, do not retry
} Prevention
- Prefer iterating getTokens() over index-based access
- Treat getTokenCount() as an exclusive upper bound
- Guard the empty-formula case (0 tokens) before accessing getToken(0)
When it happens
Trigger: Off-by-one loop: for ($i = 0; $i <= $parser->getTokenCount(); $i++) - the last iteration is out of range; calling getToken() on a parser constructed with ''; keeping a token index across a re-parse of a different formula.
Common situations: Walking tokens to rewrite formulas (bulk reference rewriting); token-stream analysis tooling; processing migrated sheets where some cells contain empty formula strings.
Related errors
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/27e937770d25a790.
Report an issue: GitHub.