# Untag Conversation

Remove one or more tags from this conversation — the other half of Tag Conversation, so a flow can clear a state it no longer applies.

## Getting here

**Automate → Workflows**, open a workflow, click **+** on the canvas, then pick **Untag Conversation** under **Add Steps**.

## Before you start

- An **owner**, **admin** or **agent** can add this step and save the workflow. Publishing that workflow — the thing that makes it run on live conversations — is an **owner** or **admin** action.
- Building and running workflows depends on your plan; see [pricing](/pricing).
- Nothing outside Inchat has to be connected. The step only writes to this conversation.

## Set up

1. Open the workflow and click **+** where the removal belongs.
2. Pick **Untag Conversation**.
3. Leave **Action** on **Remove Tag** and **On** on **Conversation** — switching either turns this into Tag Conversation, Tag Contact or Untag Contact instead, since all four share one editor.
4. Pick one or more tags from the chips.
5. Save the step, then publish the workflow. A saved but unpublished workflow removes nothing.

## Fields

| Field | What it means | Default | Limits |
| --- | --- | --- | --- |
| Action | Add Tag or Remove Tag. | Remove Tag | Choosing **Add Tag** saves this as the Tag Conversation step instead. |
| On | Whether the tag comes off the conversation or off the contact behind it. | Conversation | Choosing **Contact** saves this as the Untag Contact step instead. |
| Tags | Chips for every tag already used somewhere in the workspace. Several may be picked on one step. | — | A free-text box to type a name only appears when the workspace has no tags at all yet — with any tag already in the workspace, Remove offers chips only, so you cannot type a name that is not on the list. |

## How it works

- The step rewrites `conversations.tags` with the named tag taken out — the same column **Tag Conversation** writes.
- Removing a tag the conversation does not carry — including one that only differs in letter case from what the conversation actually has — is a no-op success: nothing is written and the step still counts as ok, so a branch can clear a whole set of mutually exclusive tags without first checking which one is set.
- Naming several tags on one step tries every one of them, even if an earlier one in the list failed to write, and the step is recorded failed if any of them did.
- Removal matching is exact and case-sensitive against whatever is currently stored — the workspace's tag list holds one canonical spelling per name (folded there when the tag was added), so naming this step's tag in a different case than that stored spelling is the no-op above, not a match. Picking from the chips always gets the exact stored spelling; typing a guess is the only way to miss it.
- When the conversation has a linked contact, the removal is also logged to that contact's Activity tab, marked as removed by a workflow (or by the AI agent, when the step runs inside an AI turn).

## When it fails

- The only realistic failure is a database error reading or writing the conversation — rare and transient. This action does not report a specific reason, so the run's **Activity** tab shows the fixed line **failed without a reported reason** rather than anything naming the tag.
- A failed removal does not stop the run: the step is recorded failed and the flow moves straight to the next one, so a message or close placed after it still happens with the tag still on the conversation.

## Limits

- It never touches the contact's own tags — clearing a tag Tag Contact added needs **Untag Contact** instead.
- It cannot remove a tag that was never there to begin with in a way that is visible — success and no-op look identical in the run log.
- The removal only ever applies to this one conversation; it does not reach any other conversation the same contact has open or has had before.

## Use cases

- Remove `needs-quote` once **Quote / confirm order** has sent a price, so the saved view for open quote requests only shows the ones still waiting.
- Clear `escalated` after **Assign To (human)** hands the thread to a person, so the tag only ever marks the time it spent unassigned.

## Related

- [Tag Conversation](https://inchat.inseller.my/help/workflows/tag-conversation)
- [Tag Contact](https://inchat.inseller.my/help/workflows/tag-contact)
- [Untag Contact](https://inchat.inseller.my/help/workflows/untag-contact)
- [Conditions and variables](https://inchat.inseller.my/help/workflows/conditions-and-variables)
- [Workflows: how a flow runs](https://inchat.inseller.my/help/workflows/workflows-overview)

---

Source files: `src/lib/workflows/ai-builder/spec.ts`, `src/lib/workflows/canvas-model.ts`, `src/components/workflows/WorkflowStepConfigDrawer.tsx`, `src/lib/workflows/engine-record-actions.ts`, `src/lib/workflows/engine.ts`, `src/lib/workflows/form-payload.ts`, `src/lib/workflows/workflow-input-schema.ts`, `src/lib/activity/record.ts`, `supabase/migrations/20260911210000_tags_catalog.sql`
