openai / openai/codex

[macOS][Codex App][Plugins/Hooks] Removed plugin Stop hook keeps running until full app restart

Open
#38,339 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug hooks skills
Dominant language
Rust
Stars
125k
Forks
19.5k
PR merge metrics
PR metrics pending

Description

What version of the Codex App are you using (From “About Codex” dialog)?

26.803.41515 (build 6321)

What subscription do you have?

Pro

What platform is your computer?

Darwin 25.4.0 arm64 arm

What issue are you seeing?

Summary

After a plugin that provides lifecycle hooks was removed, an already-running
Codex Desktop session continued invoking the plugin's previously loaded
Stop hook.

The disposable plugin source directory and its launcher had already been
removed. Nevertheless, after every subsequent assistant response, Codex tried
to execute the deleted launcher again and displayed the same ENOENT error.

The stale hook stopped running only after I fully quit and restarted Codex
Desktop.

Observed error

The original path has been redacted:

python: can't open file '/private/tmp/[REDACTED_PLUGIN_ROOT]/[REDACTED_PLUGIN]/recall_gate_a_launcher.py': [Errno 2] No such file or directory

The same error was emitted repeatedly by the cached Stop hook after subsequent turns.

Important context

The same error was emitted repeatedly by the cached Stop hook after
subsequent turns.
Important context
The plugin hook command referenced a launcher under a disposable local
marketplace directory. I understand that relying on an ephemeral absolute path
was a defect in the plugin packaging.
The Codex App behavior I am reporting is separate: after the plugin was
removed and its source directory was cleaned up, the active Desktop process
continued executing the previously loaded hook without warning that a restart
was required.
This left the plugin in a confusing partially removed state:
The plugin and its source directory had been removed.
The current Desktop process still invoked its old Stop hook.
The same missing-file error appeared after every response.
A full Codex Desktop restart was the only way to clear the stale hook.
Impact
Removing a plugin does not appear to fully deactivate its hooks in existing
Desktop sessions.
Users receive repeated hook errors after every turn.
The UI does not explain that a full app restart is required.
It is unclear whether other capabilities from the removed plugin remain
active in memory.
Workaround
Fully quit Codex Desktop, make sure the process has exited, and reopen it.
Related issue
This may be related to hook-registry reload behavior discussed in:
https://github.com/openai/codex/issues/17636

What steps can reproduce the bug?
What steps can reproduce the bug?
1. Create or install a local Codex plugin that provides a command-based
   `Stop` hook.

2. Enable the plugin and trust its hooks.

3. Start a new task in Codex Desktop and confirm that the plugin's `Stop` hook
   runs after a response.

4. Keep Codex Desktop running and keep the existing task open.

5. Remove the plugin and its local marketplace entry, then clean up the
   disposable plugin source directory containing the hook launcher.

6. Send another message in the existing task and wait for the response to
   finish.

7. Observe that Codex Desktop still invokes the removed plugin's cached
   `Stop` hook and reports that the launcher file no longer exists.

8. Send another message. Observe that the same stale-hook error is emitted
   again.

9. Fully quit Codex Desktop and reopen it.

10. Observe that the stale hook is no longer invoked after the restart.

No account credentials, network access, or external services are required to
reproduce this behavior.

### What is the expected behavior?

After a plugin is removed or disabled, its hooks should not continue running
for subsequent events.

Any of the following behaviors would be acceptable:

1. Codex invalidates or rebuilds the effective hook registry when the plugin is
   removed or disabled.

2. Codex keeps the plugin files alive until every session using its loaded
   hooks has ended, then safely removes them.

3. If live hook unloading is intentionally unsupported, Codex clearly informs
   the user that a full application restart is required before plugin removal
   is complete.

4. If a previously loaded plugin hook can no longer be resolved, Codex disables
   that stale handler after a bounded failure instead of reporting the same
   missing-file error after every turn.

The app should not silently remain in a state where the plugin appears removed
but its cached lifecycle hooks continue executing.

### Additional information

I would be happy to provide a focused regression test, additional diagnostics,
or a potential implementation outline if that would help.

I understand that unsolicited pull requests are not accepted and will wait for
an explicit maintainer invitation before submitting any code changes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing Codex Desktop's plugin hook registry and the Stop-hook lifecycle around plugin removal or disablement, using related issue #17636 as context. Reproduce the removal and restart sequence, then verify that subsequent responses no longer invoke the removed hook or repeatedly report its missing launcher.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust
Domain
desktop, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.