/goal cannot create a new goal in the same thread after previous goal is complete

Resolved 💬 4 comments Opened Jun 16, 2026 by jepson66 Closed Jun 18, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What happened?

After completing a /goal in an interactive Codex thread, the CLI/tooling still refuses to create a second goal in the same thread.

The existing goal is already marked as complete, but creating another goal fails with:

cannot create a new goal because this thread already has a goal; use update_goal only when the existing goal is complete

This is confusing because the goal is already complete. Re-entering/resuming the same thread does not release the goal state.

Expected behavior

Once a thread goal is marked as complete, one of these should be possible:

  1. Creating a new /goal in the same thread, or
  2. A clear built-in command/action to archive/delete/replace the completed goal, or
  3. A clearer error explaining that /goal is intentionally one-per-thread forever.

Actual behavior

The completed goal remains associated with the thread and blocks any subsequent /goal creation. The error message suggests using update_goal only when the existing goal is complete, but the existing goal is already complete.

Local diagnostics

Codex version:

codex-cli 0.131.0

Feature flag:

goals experimental true

Local state observations:

  • ~/.codex/state_5.sqlite contains a thread_goals record for the current thread.
  • The record status is complete.
  • ~/.codex/goals_1.sqlite exists, but its thread_goals table is empty in this environment.
  • The schema in state_5.sqlite has thread_id TEXT PRIMARY KEY, so the thread can only hold one goal record.

Observed schema:

CREATE TABLE thread_goals (
  thread_id TEXT PRIMARY KEY NOT NULL,
  goal_id TEXT NOT NULL,
  objective TEXT NOT NULL,
  status TEXT NOT NULL CHECK(status IN ('active','paused','blocked','usage_limited','budget_limited','complete')),
  token_budget INTEGER,
  tokens_used INTEGER NOT NULL DEFAULT 0,
  time_used_seconds INTEGER NOT NULL DEFAULT 0,
  created_at_ms INTEGER NOT NULL,
  updated_at_ms INTEGER NOT NULL
);

Why this matters

The /goal workflow is useful for phased project work. A common pattern is:

  1. Goal 1: standardize project structure
  2. Goal 2: refactor database access layer
  3. Goal 3: abstract AI providers

Currently, after Goal 1 is complete, Goal 2 cannot be created in the same thread. Opening a new thread loses useful context, and manually deleting local SQLite state is risky and not a reasonable user workflow.

Suggested fix

Support one of the following:

  • Allow create_goal when the existing goal status is complete by replacing/archiving the old record.
  • Add a supported command to clear/archive a completed goal from the current thread.
  • Improve the error message if one-goal-per-thread is intentional.

Environment

  • macOS
  • Codex installed via npm package @openai/codex
  • Version: 0.131.0

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 2 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #28430

Powered by Codex Action

jepson66 · 2 months ago

Thanks. This does look related to #28430.

One additional detail from my local environment: the completed goal remains in
~/.codex/state_5.sqlite with status=complete, and the table schema uses
thread_id as the primary key. So the same thread can only hold one goal
record.

The problem I hit is specifically in the agent-visible create_goal path: even
though the previous goal is complete, create_goal still refuses to create a
new goal in the same thread. This makes it hard for the assistant to continue
phased work without opening a new thread or manually touching local SQLite
state.

Keeping this open in case the session-state detail is useful.

MakenRosa · 2 months ago

I checked this against current main, and this looks fixed in the current goal extension path rather than still matching the 0.131.0 behavior from the report.

Relevant code path:

  • The agent-visible create_goal tool is handled in ext/goal/src/tool.rs::handle_create(...).
  • It calls state_db.thread_goals().insert_thread_goal(...), not the unconditional replace_thread_goal(...) service path.
  • state/src/runtime/goals.rs::insert_thread_goal(...) uses ON CONFLICT(thread_id) DO UPDATE ... WHERE thread_goals.status = 'complete'.
  • If the existing goal is not complete, the SQL returns no row and the tool responds with: cannot create a new goal because this thread has an unfinished goal; complete the existing goal first.
  • If the existing goal is complete, the same primary-key row is replaced with a new goal_id, objective, active status, and zeroed usage counters.

There is also a targeted regression test now: ext/goal/tests/goal_extension_backend.rs::installed_goal_tools_only_replace_complete_goal. It creates a first goal, verifies duplicate creation fails while it is unfinished, completes it via update_goal, then verifies a replacement create_goal succeeds with status active and tokensUsed = 0.

I ran the focused test locally in WSL:

cargo test -p codex-goal-extension installed_goal_tools_only_replace_complete_goal

Result: passed (1 passed).

So I think this issue is likely version-skew from 0.131.0. The thing worth verifying on a current release is whether the installed app/CLI is actually using this newer codex-goal-extension path and the newer goals DB schema. If a current build still reproduces it, I would look for a second path using GoalService::set_thread_goal(...) or an older bundled extension being loaded instead of the current tool implementation.

jepson66 · 2 months ago

@MakenRosa Thanks ,The issue was confirmed to be a version deviation problem in version 0.131.0, and it has been fixed after restarting in version 0.140.0.