-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
llm PHP extension crashes PHP (assert in Zend) during Llm::complete() — “Exceptions must implement Throwable” / follow-up LLMException at shutdown
Environment:
- Product: Manticore Buddy (Swoole runtime), plugin uses llm PHP extension
- PHP 8.4.17 (cli) (built: Feb 6 2026 01:17:54) (NTS DEBUG)
- OS/container: (test-kit)
- LLM provider/model: openai:gpt-3.5-turbo (model id string: openai:gpt-3.5-turbo)
Summary:
Calling Llm::complete() can crash the PHP process (exit code 134) with an assertion in Zend/zend_exceptions.c:
Assertion 'instanceof_function(exception_ce, zend_ce_throwable) && "Exceptions must implement Throwable"' failed.
In the real app (Swoole worker), this manifests as Fatal error: Uncaught exception LLMException in Unknown on line 0 during shutdown / request end.
Impact:
- Hard crash of PHP process / Swoole worker
- Not catchable from userland try/catch (Throwable $e)
- Leaves application in inconsistent state (task result not set, request handler returns wrong error)
Reproduction (Minimal):
Run inside a PHP environment where the llm extension is available.
<?php declare(strict_types=1);
function padToLength(string $text, int $targetLength): string {
$len = strlen($text);
if ($len >= $targetLength) return $text;
$padLen = $targetLength - $len;
return $text . "\n\nPAD:" . str_repeat('x', max(0, $padLen - 6));
}
function doComplete(\Llm $llm, string $label, string $prompt, float $temperature, int $maxTokens): void {
echo "== {$label}\n";
echo "prompt_length=" . strlen($prompt) . "\n";
$llm->setTemperature($temperature);
$llm->setMaxTokens($maxTokens);
$messages = [\Message::user($prompt)];
echo "complete() start\n";
try {
$response = $llm->complete($messages);
echo "complete() ok\n";
echo "finish_reason=" . $response->getFinishReason() . "\n";
$usage = $response->getUsage();
echo "tokens_total=" . $usage->getTotalTokens() . " prompt=" . $usage->getPromptTokens() . " output=" . $usage->getOutputTokens() . "\n";
} catch (\Throwable $e) {
echo "complete() caught: " . $e::class . ": " . $e->getMessage() . "\n";
}
echo "complete() end\n";
}
$modelId = 'openai:gpt-3.5-turbo';
$llm = new \Llm($modelId);
// Prompts sized to match production logs (might matter)
$intentPrompt = padToLength("intent prompt\n", 1736);
$queryGenPrompt = padToLength("query generation prompt\n", 2661);
$expansionPrompt = padToLength("expansion intent prompt\n", 1455);
doComplete($llm, 'intent_classification', $intentPrompt, 0.1, 50);
doComplete($llm, 'query_generation', $queryGenPrompt, 0.3, 200);
// This call crashes PHP with Zend assertion:
doComplete($llm, 'expansion_intent', $expansionPrompt, 0.1, 10);
echo "done\n";
Observed result:
- First two calls: complete() ok
- Third call: PHP process aborts (exit code 134) with:
php: .../Zend/zend_exceptions.c:857: zend_throw_exception_zstr: Assertion `instanceof_function(exception_ce, zend_ce_throwable) && "Exceptions must implement Throwable"' failed.
Notes / extra context:
- In a Swoole worker (single-process, long-lived), this causes worker crashes at request shutdown with:
Fatal error: Uncaught exception LLMException in Unknown on line 0 - The crash happens after complete() start and before any userland catch/finally can run, suggesting the extension raises an invalid exception or corrupts exception state internally.
- Reproduces both when running only the “expansion intent” call and when doing 2 successful completes first and crashing on the 3rd.
Script output
== intent_classification
prompt_length=1736
complete() start
complete() ok
finish_reason=stop
tokens_total=227 prompt=227 output=0
complete() end
== query_generation
prompt_length=2661
complete() start
complete() ok
finish_reason=stop
tokens_total=343 prompt=343 output=0
complete() end
== expansion_intent
prompt_length=1455
complete() start
php: /home/runner/work/executor/executor/build/Zend/zend_exceptions.c:857: zend_throw_exception_zstr: Assertion `instanceof_function(exception_ce, zend_ce_throwable) && "Exceptions must implement Throwable"' failed.
Aborted
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels