You open the Codex PR. The title is “Update components.” The body says “Refactored several components for better readability.” That is it: 12 files changed, 400 lines of diff, no explanation of what changed, why, or how it was tested. As a reviewer you now have to read the entire diff cold, with no model of the author’s intent.
Fastest fix: add a .github/pull_request_template.md with the exact sections you want, then add an AGENTS.md block telling Codex to fill every section from its own commit log. If you trigger PRs from the Codex Cloud web UI (the “Create PR” button), there is one extra catch covered below: as of June 2026 that button does not auto-apply your repo’s PR template, so you also need the agent to open the PR through the gh CLI.
This is not a Codex capability problem. The agent writes a strong PR description when you ask for one. The default is weak because most repos have no PR template, no AGENTS.md rule about description format, and the model fills the void with vague phrasing.
Which bucket are you in
| Symptom | Most likely cause | Jump to |
|---|---|---|
| Template exists, but only PRs from the Codex web UI ignore it | Cloud “Create PR” button bypasses the template | Cause 1 |
ls .github/pull_request_template.md is empty | No PR template in the repo | Cause 2 |
| Template fills, but every section stays vague | AGENTS.md has no PR-format rule | Cause 3 |
| PR body length tracks your one-line task prompt | Prompt is the bottleneck | Cause 4 |
| GitHub body is shorter than the agent transcript | Harness truncated the body | Cause 5 |
| PR body is byte-identical to the first commit subject | Agent reused the commit message | Cause 6 |
Common causes
1. Codex Cloud “Create PR” button skips the template
This one is easy to miss because the template is in the repo and PRs opened from the CLI look fine. As of June 2026 the Codex Cloud web UI “Create PR” button writes its own auto-generated summary straight into the PR body and does not apply .github/pull_request_template.md (tracked upstream as openai/codex issue #6750). So your Fixes #123 line and your section headers never appear, and the PR does not auto-close its linked issue.
The same task run through the Codex CLI (codex opening the PR via gh pr create --template ...) fills the template correctly. The divergence is the tell.
How to spot it: the template renders for hand-opened PRs and CLI-opened PRs, but PRs created by the cloud agent’s button are missing every template section. Fix is in Step 1 (open PRs through the CLI, not the button).
2. Repo has no PR template
When you click “New pull request” the body is empty. Codex has nothing to anchor on, so it produces one sentence and moves on.
How to spot it: ls .github/pull_request_template.md returns nothing (also check the repo root and docs/). The PR description starts directly with the model’s prose.
3. AGENTS.md says nothing about PR descriptions
Codex reads AGENTS.md for repo conventions. If the file has zero guidance on PR format, the agent falls back to its training-data default, which tends toward generic.
How to spot it: grep -i 'pull request\|pr description\|pr body' AGENTS.md returns nothing.
4. The task prompt is itself one line
You said “fix the date picker bug.” Codex’s PR body is roughly as detailed as your prompt. Short input, short output.
How to spot it: Compare the Codex task description with the PR body. If both are one sentence, the prompt is the bottleneck.
5. Agent’s harness truncates the PR body
Some Codex wrappers send the PR body via a CLI flag that has a length cap, or pipe it through a script that strips newlines. The model wrote a detailed body; the upload was truncated. (Note: gh pr create --body itself has no practical length cap, so suspect a custom wrapper, not gh.)
How to spot it: Compare the body in git log (or the agent transcript) with what is on GitHub. If GitHub’s body is shorter, the harness ate it.
6. Codex reused the first commit message as the body
Without other guidance, the agent copies the first commit subject as both title and body. Result: the PR body is identical to the commit subject, with no detail beyond it.
How to spot it: Check whether the PR body equals the first commit message. If yes, the harness or prompt did not request a richer body.
Shortest path to fix
Step 1: Add and enforce a PR template
Create .github/pull_request_template.md. GitHub recognizes this file in three locations: the repo root, .github/, or docs/; the filename is case-insensitive (pull_request_template.md and PULL_REQUEST_TEMPLATE.md both work). The template only takes effect once it is merged into the default branch, so commit it to main before testing.
## What changed
<one paragraph summary>
## Why
<the problem, motivation, or linked issue>
## Before / After
<for behavior changes: describe or screenshot before and after>
## How I tested
- [ ] `npm test` passes locally
- [ ] manual check: <steps>
- [ ] new tests added for <case>
## Risk
<what could break, who depends on the changed code>
## Related
<linked issues, related PRs>
GitHub auto-populates the PR body with this template for hand-opened and CLI-opened PRs, and Codex fills the empty sections.
If you use Codex Cloud’s “Create PR” button, the template is not applied automatically (cause 1). Force PR creation through the CLI instead so the template is honored. The cleanest place is your Codex Cloud environment setup script (for example scripts/codex/cloud/startup.sh), which can wrap gh so every PR is opened with the template:
gh pr create --template .github/pull_request_template.md
Then add a line to AGENTS.md so the agent opens PRs via the CLI rather than the web button:
Always open pull requests with `gh pr create --template .github/pull_request_template.md`.
Do not use the Codex web "Create PR" button, which skips the template.
Step 2: Add an AGENTS.md instruction
Append to AGENTS.md:
## PR description
Every PR you open must follow `.github/PULL_REQUEST_TEMPLATE.md` exactly. Fill
every section. Specifically:
- **What changed**: list the user-visible behavior changes or the structural
changes by file path. Not "refactored components" — say "Extracted
`useSession` from `Header.tsx` so the dashboard can reuse it."
- **Why**: link the issue if one exists, or describe the bug / requirement.
- **Before / After**: for UI or behavior changes, show both states.
- **How I tested**: list the actual commands you ran, not "tested locally."
- **Risk**: name at least one place that could break.
If a section does not apply, write "N/A — <reason>", not blank.
This converts a template into enforced structure.
Step 3: Use the commit log to draft the body
Add this guidance to AGENTS.md:
When drafting the PR body, base "What changed" on the commit log:
git log --reverse origin/main..HEAD --pretty=format:'- %s'
Each commit becomes a bullet in "What changed." Then expand each bullet with
one sentence of context. This way the PR body matches the actual changes.
The agent now has a concrete source for the description, not vibes.
Step 4: Validate description length in CI
Add a workflow that fails PRs with a too-short body:
# .github/workflows/pr-description.yml
name: PR description check
on:
pull_request:
types: [opened, edited, synchronize]
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Require non-trivial description
env:
BODY: ${{ github.event.pull_request.body }}
run: |
if [ -z "$BODY" ] || [ ${#BODY} -lt 200 ]; then
echo "PR body is too short (need 200+ chars). Use the template."
exit 1
fi
for section in "What changed" "Why" "How I tested"; do
if ! echo "$BODY" | grep -q "$section"; then
echo "Missing section: $section"
exit 1
fi
done
Required-status-check this workflow and Codex cannot land with a one-liner.
Step 5: Write better task prompts
The agent mirrors your prompt’s detail. Use a prompt template:
TITLE: <one sentence, imperative mood>
CONTEXT: <why this matters, link the issue>
SCOPE: <files / glob>
ACCEPTANCE:
- <specific test or behavior 1>
- <specific test or behavior 2>
NOTES FOR PR BODY:
- mention <X> in "Before / After"
- link issue #<N>
Codex turns these notes into PR sections.
How to confirm it’s fixed
Open one new PR through your normal Codex flow and check, on the GitHub PR page itself (not the transcript):
- The body contains every template heading (
What changed,Why,How I tested, etc.), none left blank. What changedlists specific file paths or behaviors, not “refactored components.”How I testednames the actual commands run (for examplenpm test), not “tested locally.”- If you linked an issue, the PR shows it under “Development” and will auto-close it on merge (this is the
Fixes #Nline that the Cloud button used to drop). - The
PR description checkworkflow shows a green check, not a red X.
If step 5 is red but the body looks fine, your section headers do not match the strings the workflow greps for; align them exactly.
FAQ
Why does the template work from the CLI but not from the Codex web button?
As of June 2026 the Codex Cloud “Create PR” button writes its own auto-summary into the body and skips .github/pull_request_template.md (openai/codex #6750). The CLI path runs gh pr create, which applies the template. Route PR creation through the CLI (Step 1) until OpenAI ships a fix.
Does AGENTS.md or CLAUDE.md control this?
Codex reads AGENTS.md. Put PR-format rules there. CLAUDE.md is Claude Code’s file and Codex ignores it; if you support both agents, keep the PR-format block in AGENTS.md and reference it from CLAUDE.md.
The PR body is detailed but the title is still “Update components.” How do I fix the title?
Add a title rule to AGENTS.md (“PR title = imperative summary under 60 chars, no generic verbs like Update/Refactor alone”) and have the agent derive it from the most significant commit, not the first one.
Can I require the template without a CI gate? You can, but nothing enforces it. A required status check (Step 4) is what actually blocks a one-line body from merging. Branch protection then makes the green check mandatory.
Where does GitHub look for the template, and why isn’t mine loading?
Root, .github/, or docs/, filename pull_request_template.md (case-insensitive). The most common miss: it only applies after it is merged to the default branch, so a template living only on a feature branch will not populate.
Prevention
- Ship
.github/pull_request_template.mdwith the sections you actually want, merged to the default branch - Tell
AGENTS.mdto fill every template section and forbid “N/A” without a reason - On Codex Cloud, open PRs via
gh pr create --template, not the web button - Have the agent draft “What changed” from
git log, not from a fresh summary - CI-check PR body length and section headers as a required status check
- Provide structured task prompts so the agent has material for the PR body
- Inspect the actual GitHub PR body, not the transcript; the harness may truncate