# Common Pitfalls and Data Loss Scenarios When Using AI Assistant Tools Like TodoWrite

> Discover common pitfalls and data loss risks with AI assistant tools like TodoWrite. Learn how stateless architecture, concurrent operations, and unpersisted session states can cause data loss.

- Repository: [Lucas Valbuena/system-prompts-and-models-of-ai-tools](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools)
- Tags: best-practices
- Published: 2026-02-25

---

**The TodoWrite tool's stateless, overwrite-based architecture creates race conditions and data loss risks when multiple operations run concurrently, when destructive commands are embedded in task descriptions, or when session state is not persisted across conversations.**

The `x1xhlol/system-prompts-and-models-of-ai-tools` repository exposes the internal tool definitions for AI coding assistants, including the `TodoWrite` and `TodoRead` primitives used by Claude Code, Cursor, and v0. While these tools help manage complex development workflows, their stateless design introduces specific common pitfalls and potential data loss scenarios that developers must understand to avoid corrupted state or accidental destructive operations.

## Architectural Foundations

In `Anthropic/Claude Code/Tools.json`, the `TodoWrite` tool is defined as a JSON-based API that creates, updates, or deletes entries in a shared todo list. The schema enforces three required fields: `content` (string), `status` (enum: `pending`, `in_progress`, `completed`), and a unique `id` (string). Because the tool is **stateless**, every call overwrites the entire list with the supplied array, simplifying synchronization but introducing specific failure modes when multiple writes happen concurrently.

The companion `TodoRead` tool provides read-only access to the current list, while `v0 Prompts and Tools/Tools.json` defines a higher-level `TodoManager` that recommends when to split a project into milestone-level tasks versus skipping the todo system entirely. According to the `TodoManager` specification, the todo system should only be used for **complex multi-step work**, and lists should be kept to **≤ 7 milestones** to remain manageable.

## Common Pitfalls

### Over-Granular or Trivial Tasks

A frequent mistake is creating dozens of one-line items (e.g., “run lint” or “fix typo”). This violates the `TodoManager` guidance that todos are only useful for complex multi-step work. When the list becomes noise, users lose sight of real milestones, and the assistant may skip critical steps because they are buried in trivial entries.

### Including Operational Actions Inside Todo Items

The `Cursor Prompts/Agent Prompt 2.0.txt` explicitly warns: “Todo items should NOT include operational actions done in service of higher-level tasks.” For example, an entry such as “run `npm install`” or “delete [`temp.js`](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/temp.js)” should never appear in the list. If the assistant later overwrites the list with a new array that omits these operational commands, the installation or cleanup step may be skipped, leaving the environment in an inconsistent state.

### Parallel Todo Writes and Race Conditions

Because `TodoWrite` replaces the entire list atomically, concurrent calls create race conditions. If the assistant issues two writes simultaneously—one marking a task `in_progress` and another adding a new task—the later write wins, discarding the earlier changes. The `Cursor Prompts/Agent Prompt 2.0.txt` “Parallel Todo Writes” section recommends serializing writes or using a single batch write that contains all pending modifications.

### Mis-Classification of Destructive Operations

The repository’s broader safety policy, documented in `Open Source prompts/Bolt/Prompt.txt`, marks operations such as `DROP`, `DELETE`, file-system removal, or `git reset --hard` as **FORBIDDEN** unless the user explicitly requests them. The todo system itself does not enforce these restrictions, so the assistant must cross-check each item against the destructive rule set. A todo entry such as “Drop `users` table” can lead to automatic code generation that executes the migration without explicit approval, resulting in irreversible data loss.

### Losing Context After a Session Ends

The todo list lives only in the current LLM interaction and is not persisted across sessions. When the user restarts the conversation, the previous list is gone, and the assistant loses track of completed and pending milestones.

## Potential Data Loss Scenarios

### Accidental File Deletion via Operational Actions

When operational commands are embedded in todo content, the assistant may execute them without validation. For example, a todo item with `"content": "Delete src/tmp.js"` could trigger an automated file removal. Because the todo system in `Anthropic/Claude Code/Tools.json` does not filter for destructive file operations, the assistant must implement a cross-reference against the repository’s destructive-action whitelist.

### Database Schema Rollback

A todo entry such as `"content": "Drop orders table from the database"` appears in the list, and the assistant generates migration code to execute it. According to `Open Source prompts/Bolt/Prompt.txt`, such SQL commands are marked as **FORBIDDEN** unless explicitly requested. The todo layer has no built-in guard, so the assistant must block generation and surface an explicit warning.

### Overwrite of In-Progress Work

A later parallel `TodoWrite` overwrites a list where an item is marked `in_progress`. The assistant thinks the task is already done and discards the partially edited file. This occurs because the tool replaces the entire list without merge logic. To prevent this, serialize writes or embed a version token in the payload and reject stale writes.

### Loss of Milestone Ordering

Items are added out of order due to concurrent writes, causing later implementation steps to miss dependencies. The lack of ordering enforcement means that a task with `"id": "2"` might be processed before `"id": "1"` if the second write arrives first. Enforce a monotonic `id` or `order` field and reject writes that would reorder completed milestones.

### Silent Truncation of Long Content

JSON payload exceeds internal size limits, causing the tail of the content to be dropped. Implicit size caps in the tool implementation can truncate a todo description mid-sentence, leading to ambiguous instructions. Keep each `content` concise (< 200 characters) and split large tasks into sub-tasks.

## Safe Usage Patterns

### Creating a Proper Todo List

```json
{
  "todos": [
    {
      "id": "1",
      "content": "Add dark‑mode toggle component to Settings page",
      "status": "pending"
    },
    {
      "id": "2",
      "content": "Update theme provider to expose `dark` and `light` modes",
      "status": "pending"
    },
    {
      "id": "3",
      "content": "Write unit tests for theme switching logic",
      "status": "pending"
    }
  ]
}

```

Call the `TodoWrite` tool with the payload above. Each entry is **high‑level**, non‑operational, and clearly scoped. The list contains **three** milestone‑level tasks, respecting the “≤ 7 tasks” guideline from `TodoManager`.

### Marking a Task In-Progress (Serialized Write)

```json
{
  "todos": [
    {
      "id": "1",
      "content": "Add dark‑mode toggle component to Settings page",
      "status": "in_progress"
    },
    {
      "id": "2",
      "content": "Update theme provider to expose `dark` and `light` modes",
      "status": "pending"
    },
    {
      "id": "3",
      "content": "Write unit tests for theme switching logic",
      "status": "pending"
    }
  ]
}

```

Only issue this after the previous call has been acknowledged; do **not** fire another `TodoWrite` until the assistant receives confirmation that the list has been stored.

### Guarding Against Destructive Items

```js
function isDestructive(content) {
  const keywords = [/DROP\s+/i, /DELETE\s+/i, /rm\s+-rf/i, /git\s+reset\s+--hard/i];
  return keywords.some(rx => rx.test(content));
}

// Example usage before sending to TodoWrite
const newItem = {
  id: "4",
  content: "Drop `orders` table from the database",
  status: "pending"
};

if (isDestructive(newItem.content)) {
  // Reject or ask for explicit approval
  console.warn("Destructive action detected – require user confirmation");
}

```

This snippet mirrors the repository’s **FORBIDDEN** rule set (e.g., see `Open Source prompts/Bolt/Prompt.txt` for the list of destructive SQL commands).

## Key Files in the Repository

| File | Role | Direct Link |
|------|------|-------------|
| `Anthropic/Claude Code/Tools.json` | JSON schema for `TodoWrite`/`TodoRead`, includes usage guidelines and when‑to‑use rules. | [GitHub link](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/Anthropic/Claude%20Code/Tools.json) |
| `Cursor Prompts/Agent Prompt 2.0.txt` | Provides the “Parallel Todo Writes” recommendation and examples of what to avoid. | [GitHub link](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/Cursor%20Prompts/Agent%20Prompt%202.0.txt) |
| `v0 Prompts and Tools/Tools.json` | Defines `TodoManager` – the higher‑level policy about task granularity and when to skip the todo system. | [GitHub link](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/v0%20Prompts%20and%20Tools/Tools.json) |
| `Open Source prompts/Bolt/Prompt.txt` | Lists forbidden destructive operations (e.g., `DROP`, `DELETE`). | [GitHub link](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/Open%20Source%20prompts/Bolt/Prompt.txt) |
| [`README.md`](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/README.md) | High‑level overview of the repository and its purpose. | [GitHub link](https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/blob/main/README.md) |

## Summary

- **Use TodoWrite only for complex, multi‑step work**; keep lists short and high‑level.
- **Never embed low‑level commands** (e.g., `npm install`, file deletions) inside todo items.
- **Serialize writes** to avoid race conditions; follow the “Parallel Todo Writes” guidance.
- **Cross‑check for destructive keywords** before accepting a todo entry; request explicit user approval for any potentially irreversible operation.
- **Export or persist the list** if continuity across sessions is required.

By adhering to these patterns, developers can leverage the powerful coordination benefits of AI‑driven todo management while safeguarding against accidental data loss or loss of development context.

## Frequently Asked Questions

### What makes TodoWrite prone to data loss?

The tool is **stateless** and overwrites the entire todo array on every call. If two operations run concurrently, the second write replaces the first, discarding any status updates or new items added in the interim. This design is implemented in `Anthropic/Claude Code/Tools.json` to simplify synchronization, but it requires strict serialization of writes to prevent data loss.

### How can I prevent race conditions when using AI todo tools?

Follow the “**Parallel Todo Writes**” guidance in `Cursor Prompts/Agent Prompt 2.0.txt` by serializing all `TodoWrite` calls. Ensure the assistant waits for confirmation that the previous list was stored before issuing the next write. Alternatively, batch all modifications into a single write payload rather than issuing multiple incremental updates.

### Are destructive operations like DROP or DELETE blocked by TodoWrite?

No, the todo system itself does **not** enforce safety restrictions. According to `Open Source prompts/Bolt/Prompt.txt`, operations such as `DROP`, `DELETE`, `rm -rf`, or `git reset --hard` are marked as **FORBIDDEN** unless explicitly requested by the user. The assistant must validate todo content against this rule set before generating any code that could execute these commands.

### How do I preserve my todo list across AI assistant sessions?

The todo state is **not persisted** beyond the current LLM interaction. To prevent loss of context when a session ends, export the list manually (copy-paste the JSON) or implement a custom persistence layer that stores the todo array externally. The repository does not provide automatic session-to-session storage, so users must explicitly save the state if continuity is required.