---
question: Which callers do I edit before deleting a workflow?
kind: task
via_web: na
via_cli: available
via_python: available
via_api: na
via_config: na
ref_cli: git rm
ref_python: Workflow
prereq: The workflow is a `<Name>Workflow.py` file in the `workflows/` folder of a module of your project. A `@workflow` method (ABI 3.x) is deleted like any method of the module.
next:
  - /v2/capabilities/build/workflows/overview
  - /v2/capabilities/build/agents/creating-a-workflow
  - /v2/capabilities/build/agents/give-it-tools
---

> **You are reading the v2.x docs (engine modules). New projects use v3.** [Read this page in v3](/capabilities/build/workflows/delete-a-workflow) · [Migrate from 2.x to 3.0](/capabilities/upgrade/migrate-to-3)

# Delete a workflow

A workflow exists because its class sits in the module's `workflows/` folder. Delete the class and what refers to it, then restart the engine. What goes with it:

- the class and its agent tools;
- its `POST /workflows/<slug>` route;
- on ABI 3.x in a NATS project, its durable workflow `workflow.<slug>`.

On ABI 3.x, its run records stay in System › Jobs until the [retention](/v2/capabilities/build/workflows/monitor-and-cancel-a-run?via=config) prunes them. A caller that still names `workflow.<slug>` breaks in one of two ways, depending on how it looks the workflow up:

- **The lookup fails.** The module's own `self.get_workflow("workflow.customers_workflow")` raises `ValueError`, and so does another module's `self.engine.modules[id].get_workflow(...)`. A tool that does this lookup fails each time the agent calls it.
- **The start waits for ever.** `self.engine.get_workflow(module_id, name)` and `ctx.call(...)` check nothing before they start: the run stays `QUEUED`, since no module takes it, and a parent that called it waits until its own timeout. Nexus answers 404.

## Web UI

Not applicable. Nexus has no screen that deletes a workflow: a workflow is code in a module. Use the CLI or Python steps on this page. On ABI 3.x in a NATS project, after the restart, System › Jobs marks it as no longer declared by any module.

## CLI

### Find what uses it

From the project root:

```bash
grep -rn "CustomersWorkflow" src/
```

Agents that add its tools, other workflows that compose it, and module jobs that call it all import the class. Callers by name do not import it: search for the durable name too.

```bash
grep -rn "workflow.customers_workflow\|customers_workflow" src/
```

That finds `get_workflow("workflow.customers_workflow")` and `ctx.call(..., "workflow.customers_workflow", ...)`.

### Edit the callers

Change each file the search found before deleting the class, as in the [Python steps](/v2/capabilities/build/workflows/delete-a-workflow?via=python). An agent whose `New()` still imports the workflow raises `ModuleNotFoundError` when the API builds it at startup.

### Remove the files

```bash
git rm src/my_module/workflows/CustomersWorkflow.py
```

`abi new workflow` writes no test file. Remove the test if you wrote one:

```bash
git rm src/my_module/workflows/CustomersWorkflow_test.py
```

### Restart the engine

The engine and the modules discover workflows when they start:

```bash
abi dev down
abi dev up
```

With Docker Compose, run `abi stack stop`, then `abi stack start`. The commands are [`abi dev`](/user-guide/reference/cli#abi-dev) and [`abi stack`](/user-guide/reference/cli#abi-stack).

### Check it is gone

`POST /workflows/customers_workflow` answers 404 (the Workflows group of `/docs` leaves it out). On ABI 3.x in a NATS project, `GET /api/workflows` no longer lists `workflow.customers_workflow`, and in System › Jobs its past runs stay, and the workflow is marked as no longer declared by any module.

## Python

### Remove its tools from the agents

Drop the import and the `as_tools()` call from each agent's `New()`:

```python title="agents/CustomersAgent.py"
@classmethod
def New(
    cls,
    agent_shared_state: Optional[AgentSharedState] = None,
    agent_configuration: Optional[AgentConfiguration] = None,
) -> "CustomersAgent":
    ...
    tools: list = []
    # Removed:
    # from my_module.workflows.CustomersWorkflow import (
    #     CustomersWorkflow, CustomersWorkflowConfiguration,
    # )
    # tools += CustomersWorkflow(CustomersWorkflowConfiguration()).as_tools()
```

The scaffolded `New()` fills the `[TOOLS]` block of the system prompt from that list, so the prompt follows. If you wrote the tool into the prompt by hand, remove it there too.

Do this before deleting the class: an agent whose `New()` still imports the deleted module raises `ModuleNotFoundError` when the API builds it at startup.

### Remove the other callers

Workflows that build it in `__init__`, Dagster orchestrations that call it, and, on ABI 3.x, `@job` handlers that run it and durable workflows that start it with `ctx.call` need another source for that result, or go too.

### Delete the class

Delete `workflows/CustomersWorkflow.py`, and `CustomersWorkflow_test.py` if you wrote one, then restart the engine as in the [CLI steps](/v2/capabilities/build/workflows/delete-a-workflow?via=cli).

## REST API

Not applicable. No endpoint deletes a workflow: the API publishes the classes the modules loaded. Once the class is gone and the engine restarted, the kernel's `POST /workflows/<slug>` answers 404, and on ABI 3.x `POST /api/workflows/{module_id}/workflow.<slug>/runs` does too.

## Config

Not applicable. `config.yaml` has no switch for one workflow. `enabled: false` on the module's entry turns off the whole module, with all its agents and workflows. On ABI 3.x, `nats.workflows.bridge: false` unpublishes every class at once, and keeps the classes.
