> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useshipd.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Why did shipd push return a conflict (409 / exit 3)?

> Causes of a shipd push conflict and how to recover without overwriting someone else's change.

## Overview

`shipd push` exits `3` when the server returns `409 conflict`. Nothing from that push was applied. This page explains each cause and how to fix it.

```text theme={null}
Error: Flag "search-variant" changed remotely (expected version 4, remote 5). Pull and retry, or pass --force.
```

## Causes

| Message starts with | Cause |
| - | - |
| `Flag "<key>" changed remotely` | **Stale version.** Someone changed the flag's definition after your push computed its plan. |
| `Flag "<key>" environment state changed remotely` | **Stale version.** Someone changed the environment's fallthrough, rules, or enabled switch after your plan. |
| `Flag "<key>" was created concurrently` | **Concurrent create.** Someone else created the same flag key between your plan and apply. Fix it the same way as a stale version: pull and push again. |
| `A pending approval request already exists` | **Pending approval.** An earlier change to this flag in this environment is waiting for review. |
| `This operation affects an environment protected by approval policy` | **Unsupported protected operation.** You created, archived, or changed the definition of a flag in a project where an approval policy covers an environment. These changes cannot be queued for review. |

Every message is listed in [Errors](/reference/errors#push-conflict-messages).

## Fix a stale version

Start from what is live, then re-apply your edit.

**1. Save your edits**

```bash theme={null}
git stash    # or commit shipd.config.ts to a branch
```

**2. Pull**

```bash theme={null}
shipd pull --env production
```

`shipd.config.ts` and `src/generated/flags.ts` are rewritten from the server. Comments are lost.

**3. Re-apply your edit**

Compare with `git stash show -p` and make your change again on top of the pulled file.

**4. Diff and push**

```bash theme={null}
shipd diff --env production
shipd push --env production
```

The plan should contain only your change.

## Reconcile Go definitions

Pull rewrites `shipd.config.go` directly and regenerates accessors. After resolving a stale version, inspect the Go diff and then push. See [Go definitions](/config-as-code/define-flags#go-definitions).

## Fix a pending approval

Wait for a reviewer to approve or reject the open request in the dashboard, then push again. See [Approvals](/operations/approvals).

## Fix an unsupported protected operation

The push mixed a definition change with a project that has an approval policy. Make the definition change in a way your policy allows, or ask an admin to adjust the policy. See [Approval workflows](/reference/approvals).

## --force: last resort

```bash theme={null}
shipd push --force --env production
```

`--force` skips the version check and writes your file over whatever changed on the server. Use it only after you have read the other change and decided to discard it.

* It is recorded in the [audit log](/operations/audit-log) with the reason `Forced CAS override`.
* It does not bypass approval policies or pending requests. Those still exit `3` or `5`.
* It does not skip permission checks.

Details: [Conflicts](/reference/cli#conflicts).

## Next steps

* [Push, pull, and diff](/config-as-code/sync)
* [Sync flags in CI](/config-as-code/ci)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.