phpmyadmin/phpmyadmin · error · RuntimeException
Session not found.
Error message
Session not found.
What it means
FlashMessenger stores its messages in the PHP superglobal $_SESSION. initSessionStorage() bails out early if a storage reference already exists, and throws RuntimeException('Session not found.') when $_SESSION is not set — meaning session_start() was never called or the session was closed. This guards against silently losing flash messages.
Solutions
- Call session_start() before any FlashMessenger usage (ideally early in the bootstrap).
- Ensure no code calls session_write_close()/session_abort() before flash messages are read or written; move those calls after message handling.
- Enable session.use_strict_mode-compatible startup or set session.auto_start only if appropriate; otherwise explicitly start the session in tests/CLI before touching FlashMessenger.
- Check that the session save handler works and that $_SESSION is actually populated (var_dump(isset($_SESSION))).
Example fix
// before
$messenger = new FlashMessenger();
$messenger->addMessage('Saved'); // RuntimeException: Session not found.
// after
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start();
}
$messenger = new FlashMessenger();
$messenger->addMessage('Saved'); Defensive patterns
Strategy: validation
Validate before calling
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start(); // must run before any FlashMessenger usage
}
if (!isset($_SESSION)) {
throw new RuntimeException('Session unavailable; cannot use flash messages.');
} Type guard
function sessionIsActive(): bool
{
return session_status() === PHP_SESSION_ACTIVE && isset($_SESSION);
} Try / catch
try {
$messenger->addMessage('Saved');
} catch (RuntimeException $e) {
if (str_contains($e->getMessage(), 'Session not found')) {
session_start();
$messenger->addMessage('Saved'); // retry once after starting the session
} else {
throw $e;
}
} Prevention
- Always start the session in the application bootstrap before any response logic.
- Avoid session_write_close()/session_abort() until all flash messages have been consumed.
- In CLI/tests, seed $_SESSION or start a session explicitly before using FlashMessenger.
- Check session_status() early and log if the session is unexpectedly closed.
When it happens
Trigger: Calling addMessage, getMessages, or getCurrentMessages (or any code that does) before session_start() has run, after session_write_close()/session_abort(), or in a CLI/test context where no session was started.
Common situations: Session autostart disabled (session.auto_start=0) and no session_start() in bootstrap; flash message used after the response is sent and the session closed; long-running scripts that closed the session to unlock it; unit tests invoking FlashMessenger without a session fixture.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Failed to generate random CSRF token!
- Failed to store CSRF token in session! Probably sessions…
- Failed to set session cookie. Maybe you are using HTTP…
AI-assisted analysis of phpmyadmin/phpmyadmin@70d713dc39 (2026-09-13).
Data as JSON: /api/errors/b5142faf2d9c71a3.
Report an issue: GitHub.
Appendix: source
Thrown at src/FlashMessenger.php:31
final class FlashMessenger
{
private const STORAGE_KEY = 'FlashMessenger';
/** @var mixed[] */
private array|null $storage = null;
/** @psalm-var FlashMessageList */
private array $previousMessages = [];
/** @psalm-assert !null $this->storage */
private function initSessionStorage(): void
{
if ($this->storage !== null) {
return;
}
if (! isset($_SESSION)) {
throw new RuntimeException(__('Session not found.'));
}
$this->storage = &$_SESSION;
if (isset($this->storage[self::STORAGE_KEY])) {
$this->previousMessages = $this->storage[self::STORAGE_KEY];
}
$this->storage[self::STORAGE_KEY] = [];
}
public function addMessage(string $context, string $message, string $statement = ''): void
{
$this->initSessionStorage();
$this->storage[self::STORAGE_KEY][] = ['context' => $context, 'message' => $message, 'statement' => $statement];
}
View on GitHub (pinned to 70d713dc39)