Plugin SessionStart hook not automatically triggered

Resolved 💬 6 comments Opened Nov 28, 2025 by HomoYouDidnt Closed Feb 14, 2026

Bug: Plugin SessionStart hook not automatically triggered by Claude Code

Summary

The episodic-memory plugin's SessionStart hook defined in hooks/hooks.json is not being automatically loaded and executed by Claude Code, despite the plugin being enabled and the hook configuration being valid.

Environment

  • Claude Code version: Latest (Nov 2025)
  • Plugin version: episodic-memory 1.0.9
  • OS: Linux (Debian trixie)
  • Plugin source: superpowers-marketplace

Expected Behavior

According to Claude Code documentation:

"When a plugin is enabled, its hooks are merged with user and project hooks"

The plugin's SessionStart hook should automatically trigger episodic-memory sync --background when a session starts.

Actual Behavior

The SessionStart hook is never triggered. Conversations are not synced to the archive, causing the episodic memory search to return stale data.

Evidence:

  • Session started at 10:46
  • Database was only modified at 10:51 (when manual sync was triggered)
  • No sync processes were running at session start
  • Archive contained only data from Nov 4 (24 days stale) despite daily usage

Plugin Hook Configuration

~/.claude/plugins/cache/episodic-memory/.claude-plugin/plugin.json:

{
  "name": "episodic-memory",
  "version": "1.0.9",
  ...
  "hooks": "./hooks/hooks.json"
}

~/.claude/plugins/cache/episodic-memory/hooks/hooks.json:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/cli/episodic-memory sync --background",
            "async": true
          }
        ]
      }
    ]
  }
}

Comparison with Working Plugin

The superpowers plugin has a nearly identical hook structure and its SessionStart hook DOES work:

~/.claude/plugins/cache/superpowers/hooks/hooks.json:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume|clear|compact",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh"
          }
        ]
      }
    ]
  }
}

Key differences:

  1. superpowers doesn't use "async": true
  2. superpowers uses a shell script that outputs JSON
  3. superpowers has a broader matcher pattern

Workaround

Adding the hook manually to ~/.claude/settings.json works:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/plugins/cache/episodic-memory/cli/episodic-memory sync --background"
          }
        ]
      }
    ]
  }
}

Possible Causes

  1. The "async": true flag may be causing the hook to be skipped or silently fail
  2. The ${CLAUDE_PLUGIN_ROOT} variable may not be expanded correctly for async hooks
  3. Plugin hooks with async: true may not be merged correctly

Steps to Reproduce

  1. Install episodic-memory plugin from superpowers-marketplace
  2. Enable the plugin
  3. Start a new Claude Code session
  4. Check if episodic-memory sync process is running
  5. Verify conversation archive timestamps

Additional Context

The sync command works perfectly when run manually:

~/.claude/plugins/cache/episodic-memory/cli/episodic-memory sync

The MCP server for search also works correctly - only the automatic sync hook fails.

View original on GitHub ↗

This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗