flarum/framework · warning
[$errno] $errstr in $errfile:$errline
Error message
[$errno] $errstr in $errfile:$errline
What it means
ServeCommand's custom PHP error handler intercepts PHP warnings/notices/deprecations raised while the websocket server runs. For low-severity levels (E_DEPRECATED, E_USER_DEPRECATED, E_NOTICE, E_USER_NOTICE) it does NOT convert them to exceptions; in --debug mode it instead logs `[$errno] $errstr in $errfile:$errline` and returns true to suppress PHP's default handling. Higher severities are still thrown as exceptions.
Solutions
- Update the package/file named in $errfile to a version compatible with your PHP version.
- If the deprecation comes from your own code, replace the deprecated call per the message.
- Run without --debug in production if the log noise is undesirable (still fix the source).
- Confirm the message is only a deprecation/notice (errno in the low-severity set) — otherwise it would have thrown.
- Pin a known-good PHP version for the server process.
Example fix
// before (PHP 8.2) $strpos = strpos($haystack, $needle, null); // after $strpos = strpos($haystack, $needle);
Defensive patterns
Strategy: fallback
Validate before calling
// Before running the server, scan for known deprecations:
$report = error_reporting(E_ALL);
set_error_handler(function ($no, $str, $file) { var_dump([$no, $str, $file]); return true; });
require 'vendor/autoload.php';
restore_error_handler(); Type guard
$lowSeverity = in_array($errno, [E_DEPRECATED, E_USER_DEPRECATED, E_NOTICE, E_USER_NOTICE], true);
if (!$lowSeverity) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } Try / catch
try {
$server->run();
} catch (ErrorException $e) {
$this->logger->warning(sprintf('[%d] %s in %s:%d', $e->getSeverity(), $e->getMessage(), $e->getFile(), $e->getLine()));
} Prevention
- Run CI against the target PHP version to surface deprecations before deploy.
- Keep packages updated for each PHP major upgrade.
- Avoid --debug in production; log deprecations to a monitored channel instead.
- Replace deprecated PHP APIs flagged in the log promptly.
- Set a consistent error_reporting level across environments.
When it happens
Trigger: Running the realtime/websocket serve command (with --debug) triggers PHP code that emits a deprecation, notice, or warning — e.g. deprecated function usage in bundled dependencies or userland notices — producing this log line.
Common situations: PHP 8.x upgrades making previously-silent deprecations loud (e.g. dynamic properties, null-to-non-nullable args); outdated packages not yet compatible with the PHP version; debug mode enabled so the messages become visible.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- Paths are not possible in websocket connections.
- Invalid auth signature provided.
- $errno, $errstr, $errfile:$errline
- Route $name already exists
- Could not generate URL for route '$routeName': no value…
AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15).
Data as JSON: /api/errors/0a7692b7ec41efbb.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/realtime/src/Websocket/Console/ServeCommand.php:123
return (new WebsocketLogger($this->output))
->enable($debug)
->verbose($this->output->isVerbose());
});
$this->getLaravel()->bind(ConnectionLogger::class, function () use ($debug) {
return (new ConnectionLogger($this->output))
->enable($debug)
->verbose($this->output->isVerbose());
});
}
public function errorHandler(int $errno, string $errstr, string $errfile, int $errline): bool
{
// Don't throw exceptions for deprecation notices, warnings, or notices in debug mode
// Just log them to output instead
if (in_array($errno, [E_DEPRECATED, E_USER_DEPRECATED, E_NOTICE, E_USER_NOTICE])) {
if ($this->option('debug')) {
$this->warn("[$errno] $errstr in $errfile:$errline");
}
return true;
}
// Throw exceptions for actual errors
throw new \Exception("$errno, $errstr, $errfile:$errline");
}
/**
* Expire stale index-typing presence and emit falling-edge "stopped typing"
* signals, so list dots clear without each client running its own per-discussion
* timer. Swept faster than the TTL (6s) to keep the clear-lag small.
*/
protected function sweepIndexTyping(LoopInterface $loop): void
{
$presence = $this->getLaravel()->make(IndexTypingPresence::class);
View on GitHub (pinned to 4b939f6853)