Skip to content

Session::save() crashes when $data property is never initialized #273

@woprrr

Description

@woprrr

Description

Mcp\Server\Session\Session::save() throws a TypeError when $data is accessed before initialization on a newly created session that has never had data set.

Error: Typed property Mcp\Server\Session\Session::$data must not be accessed before initialization

Stack Trace

Mcp\Server\Session\Session::save()
  → return $this->store->write($this->id, json_encode($this->data, JSON_THROW_ON_ERROR));

Mcp\Server\Protocol::processInput()
  → $session->save();

Mcp\Server\Transport\BaseTransport::handleMessage()
  → ($this->messageListener)($this, $payload, $sessionId);

Mcp\Server\Transport\StreamableHttpTransport::handlePostRequest()
  → $this->handleMessage($body, $this->sessionId);

Environment

  • mcp/sdk version: v0.4.0
  • PHP version: 8.5.4
  • Transport: StreamableHttpTransport (HTTP Streamable)
  • Runtime: FrankenPHP
  • Framework: Symfony 8 with symfony/mcp-bundle

Steps to Reproduce

  1. Configure an MCP server endpoint using StreamableHttpTransport
  2. Send a valid POST request to the MCP endpoint (e.g. initialize method)
  3. The server processes the message and calls Protocol::processInput()
  4. processInput() calls $session->save()
  5. Session::save() accesses $this->data which was never initialized → TypeError

Root Cause

In Session.php line 54, $this->data is a typed property that is accessed in save() without checking if it has been initialized. When a new session is created and processInput() triggers a save() before any data has been explicitly set, the property is still uninitialized.

Suggested Fix

Initialize $data with a default value in the property declaration:

private array $data = [];

Or add a null check / initialization in the save() method:

public function save(): bool
{
    if (!isset($this->data)) {
        return true; // Nothing to persist
    }
    return $this->store->write($this->id, json_encode($this->data, JSON_THROW_ON_ERROR));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions