﻿---
title: "同一层不要同时写 hooks.json 和 [hooks]"
summary: "同一配置层里两份会合并并在启动时警告。高层配置不会替换低层钩子，重复的 SessionStart 会跑两遍。"
category: hooks
level: intermediate
surfaces: [cli]
tags: ["hooks", "hooks.json", "config.toml"]
canonical: /tips/hooks-one-representation/
---

# 同一层不要同时写 hooks.json 和 [hooks]

同一配置层里两份会合并并在启动时警告。高层配置不会替换低层钩子，重复的 SessionStart 会跑两遍。

官方 Hooks 页写明：匹配到的钩子源**全部加载**，高层不会覆盖低层。用户 `~/.codex/hooks.json`、项目 `.codex/hooks.json`、以及各层 `config.toml` 里的 `[hooks]` 会叠在一起。

同一层（例如都在 `~/.codex/`）如果既有 `hooks.json` 又有内联 `[hooks]`，Codex 会合并两边，并在启动时警告。不要复制同一份 `SessionStart` 到两个文件里指望「后面那份赢」——两边都会跑。

选一种表示法：

```toml
[[hooks.PostToolUse]]
matcher = "Bash"

[[hooks.PostToolUse.hooks]]
type = "command"
command = "python3 /home/you/.codex/hooks/post_tool_use.py"
timeout = 30
```

或只保留 `~/.codex/hooks.json`，把 `config.toml` 里的 `[hooks]` 删掉。项目层还要目录受信任才会加载。改完新开会话，用 `/hooks` 看实际来源，而不是数文件。

`prompt` / `agent` handler 会解析但跳过；真正会跑的是 `command` 和 `mcp_tool`。后台跑用 `async = true`，但 `SessionEnd` 仍强制同步。

## 来源

- [OpenAI · Hooks](https://learn.chatgpt.com/docs/hooks)
