From d6cc18be6f57c3525afd6faddb0cf676b3d0de67 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 14:27:00 +0530 Subject: [PATCH 01/10] Add troubleshooting page for a stuck Terraform state lock --- docs.json | 6 + .../stuck-terraform-state-lock.mdx | 103 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 troubleshooting/stuck-terraform-state-lock.mdx diff --git a/docs.json b/docs.json index 8a83c2c..8376379 100644 --- a/docs.json +++ b/docs.json @@ -131,6 +131,12 @@ "guides/custom-domains" ] }, + { + "group": "Troubleshooting", + "pages": [ + "troubleshooting/stuck-terraform-state-lock" + ] + }, { "group": "Module definitions", "pages": [ diff --git a/troubleshooting/stuck-terraform-state-lock.mdx b/troubleshooting/stuck-terraform-state-lock.mdx new file mode 100644 index 0000000..6faa4c0 --- /dev/null +++ b/troubleshooting/stuck-terraform-state-lock.mdx @@ -0,0 +1,103 @@ +--- +title: "Stuck Terraform state lock" +description: "Recognize a Terraform state lock that a run left behind, confirm nothing is still running, and release it from the dashboard, the CLI, or the API." +"og:image": "https://www.ravion.com/og/docs/troubleshooting/stuck-terraform-state-lock.png" +"twitter:image": "https://www.ravion.com/og/docs/troubleshooting/stuck-terraform-state-lock.png" +--- + +Terraform locks a stack's state for the length of any operation that can write it, so two runs can never write state at the same time. The lock is released when the operation finishes. + +A run that dies without finishing — a cancelled runner, a lost network connection, an infrastructure failure part-way through an apply — can leave the lock behind. Nothing holds it any more, but the state still looks busy, and the next run fails before it starts: + +```text +Error: Error acquiring the state lock + +Error message: workspace already locked +Lock Info: + ID: 6a1c1e0c-... + Operation: OperationTypeApply + Who: runner@ravion + Created: 2026-08-04 18:22:41 UTC +``` + +This is a stuck lock. Releasing it lets the stack run again. + +## Check that nothing is still running + +A lock held by a run that is still going is not stuck — it is doing its job. Interrupting it would throw away the work in flight. + +Open the stack and look at its runs. If any run is queued, in progress, or waiting for approval, wait for it to finish, or cancel it. Ravion enforces this for you: unlocking while a run is active fails, and tells you which run is holding things up. + +If the run itself is the thing that is stuck — it stays active and cancelling does not move it — `ravion stack unlock --force` releases the lock anyway. See [When the run is stuck too](#when-the-run-is-stuck-too). + + + Ravion can only release locks on stacks whose Terraform state it stores — the stacks that set + `ravion_state_backend_workspace` in their [stack config](/modules/stack). If your stack points at + a backend you manage yourself, such as S3 with DynamoDB, release the lock with that backend's own + tooling instead. + + +## Release the lock + + + + Open the stack. When its state is locked and no run is active, **Unlock stack** replaces the + **Run plan** button. Select it, and the confirmation names the run that took the lock so you + can open it and see how it ended before you release it. + + Once the lock is released the button goes back to **Run plan**. + + + + Check the lock first: + + ```bash + ravion stack lock + ``` + + Then release it: + + ```bash + ravion stack unlock + ``` + + Add `--json` to either command to get the lock as JSON. + + Unlocking refuses while a run is still active. If that run is itself stuck, add `--force` — + see [When the run is stuck too](#when-the-run-is-stuck-too). + + + + ```bash + curl -X POST https://api.ravion.com/stacks//unlock \ + -H "Authorization: Bearer $RAVION_API_KEY" \ + -H "x-organization-id: $RAVION_ORG_ID" + ``` + + `GET /stacks/{id}/lock` returns the current lock without changing it. + + + +## When the run is stuck too + +Sometimes the run holding the lock is itself stuck: it stays queued or in progress, and cancelling it does not move it. Waiting is then not a plan, and the stack cannot run again until the lock goes. + +`--force` releases the lock regardless of what is running: + +```bash +ravion stack unlock --force +``` + +Reach for it only in that case. The run is not stopped by unlocking — if its Terraform is genuinely still working, it carries on against state Ravion has stopped tracking for it, and the state it was writing is discarded when it finishes. Cancel the run first whenever cancelling actually works. + +There is no `--force` in the dashboard. The **Unlock stack** button appears only once no run is active, so forcing is a deliberate act you take from the CLI or the API. + +## What unlocking changes + +Releasing the lock discards the state write the interrupted run had started but never completed. The stack's state stays exactly as it was after its last completed operation. + +That state can be behind your real infrastructure: an apply that died part-way may have created resources that the state never recorded. Run a plan after unlocking to see the difference, and read it before applying — Terraform will propose creating anything it cannot see in the state. + +## If the lock comes back + +A lock that reappears right after you release it is a lock something is actively taking, not a stuck one. Check the stack's runs, and anywhere else that runs Terraform against the same state — a local `terraform apply`, or a CI job outside Ravion — before unlocking again. From 2d7ed83ced4e5f53c9d63a1ae7a9040393a23084 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 14:27:00 +0530 Subject: [PATCH 02/10] Regenerate stack CLI reference for lock and unlock --- cli/reference/stack.mdx | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/cli/reference/stack.mdx b/cli/reference/stack.mdx index 0465908..9d1a05e 100644 --- a/cli/reference/stack.mdx +++ b/cli/reference/stack.mdx @@ -47,6 +47,20 @@ ravion stack list [flags] | `--project-id ` | | projectId | | `-v, --verbose` | | show full output | +### `ravion stack lock` + +Read a stack's Terraform state lock + +```bash +ravion stack lock [flags] +``` + +**Flags:** + +| Flag | Required | Description | +| --- | --- | --- | +| `--json` | | emit response as JSON | + ### `ravion stack resource-count` Count current-state terraform resources for stacks @@ -79,3 +93,18 @@ ravion stack trigger-pipeline [flags] | `--autoapprove` | | Pass autoapprove=true to stack change pipeline runs when supported. | | `--json` | | emit response as JSON | +### `ravion stack unlock` + +Force-release a stack's Terraform state lock + +```bash +ravion stack unlock [flags] +``` + +**Flags:** + +| Flag | Required | Description | +| --- | --- | --- | +| `--force` | | Release the lock even while a run is still active on the stack. Use when the run itself is stuck: the running Terraform keeps operating on state Ravion has stopped tracking for it, and its state write is discarded. | +| `--json` | | emit response as JSON | + From 1b9ab769690a81f4529adf45cc4e626ec35e180c Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 14:44:33 +0530 Subject: [PATCH 03/10] Rewrite the stuck state lock page in a direct voice --- .../stuck-terraform-state-lock.mdx | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/troubleshooting/stuck-terraform-state-lock.mdx b/troubleshooting/stuck-terraform-state-lock.mdx index 6faa4c0..a5f6e88 100644 --- a/troubleshooting/stuck-terraform-state-lock.mdx +++ b/troubleshooting/stuck-terraform-state-lock.mdx @@ -1,13 +1,13 @@ --- title: "Stuck Terraform state lock" -description: "Recognize a Terraform state lock that a run left behind, confirm nothing is still running, and release it from the dashboard, the CLI, or the API." +description: "Recognize a Terraform state lock that a run left behind, confirm nothing still holds it, and release it from the dashboard, the CLI, or the API." "og:image": "https://www.ravion.com/og/docs/troubleshooting/stuck-terraform-state-lock.png" "twitter:image": "https://www.ravion.com/og/docs/troubleshooting/stuck-terraform-state-lock.png" --- -Terraform locks a stack's state for the length of any operation that can write it, so two runs can never write state at the same time. The lock is released when the operation finishes. +Terraform and OpenTofu lock a stack's state for the length of every operation that touches it. Both `plan` and `apply` take the lock — a plan refreshes state as it runs, so the lock is what keeps two operations on the same workspace from racing each other and leaving the state describing infrastructure that has moved on. The lock is released as the operation ends. -A run that dies without finishing — a cancelled runner, a lost network connection, an infrastructure failure part-way through an apply — can leave the lock behind. Nothing holds it any more, but the state still looks busy, and the next run fails before it starts: +A run can die mid-operation: a cancelled runner, a lost network connection, an infrastructure failure part-way through an apply. The lock outlives the run that took it. State stays marked busy with nothing left to release it, and the next run fails before it starts: ```text Error: Error acquiring the state lock @@ -16,40 +16,38 @@ Error message: workspace already locked Lock Info: ID: 6a1c1e0c-... Operation: OperationTypeApply - Who: runner@ravion + Who: root@ip-10-0-1-23 Created: 2026-08-04 18:22:41 UTC ``` -This is a stuck lock. Releasing it lets the stack run again. +That is a stuck lock. Releasing it lets the stack run again. -## Check that nothing is still running +## Confirm the lock is stuck -A lock held by a run that is still going is not stuck — it is doing its job. Interrupting it would throw away the work in flight. +A run that is still going holds its lock legitimately, and unlocking mid-run throws away the work in flight. -Open the stack and look at its runs. If any run is queued, in progress, or waiting for approval, wait for it to finish, or cancel it. Ravion enforces this for you: unlocking while a run is active fails, and tells you which run is holding things up. - -If the run itself is the thing that is stuck — it stays active and cancelling does not move it — `ravion stack unlock --force` releases the lock anyway. See [When the run is stuck too](#when-the-run-is-stuck-too). +Open the stack and read its runs. Queued, in-progress, and awaiting-approval runs all still own their lock — wait for them to finish, or cancel them. Ravion enforces this: unlocking during an active run fails and names the run responsible. - Ravion can only release locks on stacks whose Terraform state it stores — the stacks that set - `ravion_state_backend_workspace` in their [stack config](/modules/stack). If your stack points at - a backend you manage yourself, such as S3 with DynamoDB, release the lock with that backend's own - tooling instead. + Ravion releases locks only on stacks that store their Terraform state in Ravion — the stacks that + set `ravion_state_backend_workspace` in their [stack config](/modules/stack). Stacks pointed at a + backend you manage yourself, such as S3 with DynamoDB, keep their locks in that backend; release + those with the backend's own tooling. ## Release the lock - Open the stack. When its state is locked and no run is active, **Unlock stack** replaces the - **Run plan** button. Select it, and the confirmation names the run that took the lock so you - can open it and see how it ended before you release it. + Open the stack. **Unlock stack** takes the place of the **Run plan** button once the state is + locked with no run left to release it. Select it to see the confirmation, which names the run + that took the lock so you can open that run and read how it ended. - Once the lock is released the button goes back to **Run plan**. + The button returns to **Run plan** as soon as the lock is released. - Check the lock first: + Read the lock first: ```bash ravion stack lock @@ -63,8 +61,8 @@ If the run itself is the thing that is stuck — it stays active and cancelling Add `--json` to either command to get the lock as JSON. - Unlocking refuses while a run is still active. If that run is itself stuck, add `--force` — - see [When the run is stuck too](#when-the-run-is-stuck-too). + Unlocking refuses while a run is still active. Runs that stop making progress have their own + escape hatch — see [Runs that stop making progress](#runs-that-stop-making-progress). @@ -78,26 +76,28 @@ If the run itself is the thing that is stuck — it stays active and cancelling -## When the run is stuck too - -Sometimes the run holding the lock is itself stuck: it stays queued or in progress, and cancelling it does not move it. Waiting is then not a plan, and the stack cannot run again until the lock goes. +## Runs that stop making progress -`--force` releases the lock regardless of what is running: +A run occasionally stalls: it stays queued or in progress, and cancelling leaves it exactly where it is. The lock stays with that run, and the stack stays unusable. `--force` releases the lock regardless of what is running: ```bash ravion stack unlock --force ``` -Reach for it only in that case. The run is not stopped by unlocking — if its Terraform is genuinely still working, it carries on against state Ravion has stopped tracking for it, and the state it was writing is discarded when it finishes. Cancel the run first whenever cancelling actually works. +Save it for exactly that situation. Unlocking leaves the run alive — Terraform that is still working carries on against state Ravion has stopped tracking for it, and the state it was writing is discarded when it finishes. Cancel the run first whenever cancellation works. -There is no `--force` in the dashboard. The **Unlock stack** button appears only once no run is active, so forcing is a deliberate act you take from the CLI or the API. +The dashboard offers no `--force`. Its **Unlock stack** button waits for every run to go inactive, which keeps forcing a deliberate act you take from the CLI or the API. ## What unlocking changes -Releasing the lock discards the state write the interrupted run had started but never completed. The stack's state stays exactly as it was after its last completed operation. +Releasing the lock discards the state write that the interrupted run had started. The stack's state stays as it stood after its last completed operation. + +Your real infrastructure can be ahead of that state — an apply that died part-way may have created resources the state never recorded. Run a plan after unlocking and read it before applying: Terraform proposes creating everything it cannot see in the state. + +## Locks that come back -That state can be behind your real infrastructure: an apply that died part-way may have created resources that the state never recorded. Run a plan after unlocking to see the difference, and read it before applying — Terraform will propose creating anything it cannot see in the state. +A lock that reappears right after you release it belongs to something actively taking it. Check the stack's runs, then check everywhere else that runs Terraform against the same workspace — a local `terraform apply`, a CI job outside Ravion — before unlocking again. -## If the lock comes back +## Get help -A lock that reappears right after you release it is a lock something is actively taking, not a stuck one. Check the stack's runs, and anywhere else that runs Terraform against the same state — a local `terraform apply`, or a CI job outside Ravion — before unlocking again. +[Contact support](/contact-support) for anything this page does not cover: a lock that survives an unlock, a run that stays active for hours with no output, or a plan that reports resources as missing after you release a lock. Include the stack ID and the output of `ravion stack lock`. From d27030f88923da84472dbfab1a232f3385748d08 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 14:47:36 +0530 Subject: [PATCH 04/10] Clarify that a run holding a lock indefinitely is unexpected --- .../stuck-terraform-state-lock.mdx | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/troubleshooting/stuck-terraform-state-lock.mdx b/troubleshooting/stuck-terraform-state-lock.mdx index a5f6e88..dd9f15a 100644 --- a/troubleshooting/stuck-terraform-state-lock.mdx +++ b/troubleshooting/stuck-terraform-state-lock.mdx @@ -1,13 +1,13 @@ --- title: "Stuck Terraform state lock" -description: "Recognize a Terraform state lock that a run left behind, confirm nothing still holds it, and release it from the dashboard, the CLI, or the API." +description: "Identify a Terraform state lock left behind by an interrupted run, confirm that no operation still holds it, and release it from the dashboard, the CLI, or the API." "og:image": "https://www.ravion.com/og/docs/troubleshooting/stuck-terraform-state-lock.png" "twitter:image": "https://www.ravion.com/og/docs/troubleshooting/stuck-terraform-state-lock.png" --- -Terraform and OpenTofu lock a stack's state for the length of every operation that touches it. Both `plan` and `apply` take the lock — a plan refreshes state as it runs, so the lock is what keeps two operations on the same workspace from racing each other and leaving the state describing infrastructure that has moved on. The lock is released as the operation ends. +Terraform and OpenTofu lock a stack's state for the duration of every operation that touches it. Both `plan` and `apply` acquire the lock, because both refresh state as they run. The lock prevents two operations from working on the same workspace at once and leaving the state inconsistent. It is released when the operation completes. -A run can die mid-operation: a cancelled runner, a lost network connection, an infrastructure failure part-way through an apply. The lock outlives the run that took it. State stays marked busy with nothing left to release it, and the next run fails before it starts: +An interrupted run can leave the lock behind. Common causes are a cancelled runner, a lost network connection, and an infrastructure failure partway through an apply. The state stays locked with no operation holding it, and the next run fails immediately: ```text Error: Error acquiring the state lock @@ -20,49 +20,49 @@ Lock Info: Created: 2026-08-04 18:22:41 UTC ``` -That is a stuck lock. Releasing it lets the stack run again. +This is a stuck lock. Releasing it allows the stack to run again. ## Confirm the lock is stuck -A run that is still going holds its lock legitimately, and unlocking mid-run throws away the work in flight. +An active run holds its lock for a reason, and unlocking during a run discards work in progress. -Open the stack and read its runs. Queued, in-progress, and awaiting-approval runs all still own their lock — wait for them to finish, or cancel them. Ravion enforces this: unlocking during an active run fails and names the run responsible. +Open the stack and review its runs. Runs that are queued, in progress, or awaiting approval still hold their lock. Wait for them to complete, or cancel them. Ravion enforces this: an unlock during an active run is rejected and reports which run holds the lock. - Ravion releases locks only on stacks that store their Terraform state in Ravion — the stacks that - set `ravion_state_backend_workspace` in their [stack config](/modules/stack). Stacks pointed at a - backend you manage yourself, such as S3 with DynamoDB, keep their locks in that backend; release - those with the backend's own tooling. + Ravion can release locks only for stacks that store their Terraform state in Ravion — those that + set `ravion_state_backend_workspace` in their [stack config](/modules/stack). Stacks using a + self-managed backend, such as S3 with DynamoDB, hold their locks in that backend. Release those + with the backend's own tooling. ## Release the lock - Open the stack. **Unlock stack** takes the place of the **Run plan** button once the state is - locked with no run left to release it. Select it to see the confirmation, which names the run - that took the lock so you can open that run and read how it ended. + Open the stack. **Unlock stack** replaces the **Run plan** button while the state is locked and + no run is active. Select it to open a confirmation, which identifies the run that acquired the + lock so you can review how that run ended. - The button returns to **Run plan** as soon as the lock is released. + The button returns to **Run plan** once the lock is released. - Read the lock first: + Review the lock: ```bash ravion stack lock ``` - Then release it: + Release it: ```bash ravion stack unlock ``` - Add `--json` to either command to get the lock as JSON. + Add `--json` to either command to return the lock as JSON. - Unlocking refuses while a run is still active. Runs that stop making progress have their own - escape hatch — see [Runs that stop making progress](#runs-that-stop-making-progress). + An unlock is rejected while a run is active. See + [Runs that never complete](#runs-that-never-complete) for the one exception. @@ -72,32 +72,34 @@ Open the stack and read its runs. Queued, in-progress, and awaiting-approval run -H "x-organization-id: $RAVION_ORG_ID" ``` - `GET /stacks/{id}/lock` returns the current lock without changing it. + `GET /stacks/{id}/lock` returns the current lock without modifying it. -## Runs that stop making progress +## Runs that never complete -A run occasionally stalls: it stays queued or in progress, and cancelling leaves it exactly where it is. The lock stays with that run, and the stack stays unusable. `--force` releases the lock regardless of what is running: +Every run reaches a final state, including runs that fail. A run that stays queued or in progress and does not respond to cancellation indicates a problem beyond the stack itself. This is not expected behaviour — [contact support](/contact-support) when you encounter it. + +Such a run continues to hold the lock, and a standard unlock stays rejected. `--force` releases the lock regardless of run status: ```bash ravion stack unlock --force ``` -Save it for exactly that situation. Unlocking leaves the run alive — Terraform that is still working carries on against state Ravion has stopped tracking for it, and the state it was writing is discarded when it finishes. Cancel the run first whenever cancellation works. +Use `--force` only in this situation. The run itself continues: Terraform still executing operates on state that Ravion has stopped tracking for that run, and the state it writes is discarded. Cancel the run first whenever cancellation succeeds. -The dashboard offers no `--force`. Its **Unlock stack** button waits for every run to go inactive, which keeps forcing a deliberate act you take from the CLI or the API. +`--force` is unavailable in the dashboard. The **Unlock stack** button requires every run to be inactive, which keeps forcing a deliberate action taken through the CLI or the API. ## What unlocking changes -Releasing the lock discards the state write that the interrupted run had started. The stack's state stays as it stood after its last completed operation. +Releasing the lock discards the state that the interrupted run had begun writing. The stack's state remains as it was after the last completed operation. -Your real infrastructure can be ahead of that state — an apply that died part-way may have created resources the state never recorded. Run a plan after unlocking and read it before applying: Terraform proposes creating everything it cannot see in the state. +Your infrastructure can be ahead of that state. An apply that stopped partway can create resources that the state never recorded. Run a plan after unlocking and review it before applying: Terraform proposes creating every resource missing from the state. -## Locks that come back +## Locks that reappear -A lock that reappears right after you release it belongs to something actively taking it. Check the stack's runs, then check everywhere else that runs Terraform against the same workspace — a local `terraform apply`, a CI job outside Ravion — before unlocking again. +A lock that returns immediately after release is held by an active process. Review the stack's runs, then review every other system that runs Terraform against the same workspace, such as a local `terraform apply` or a CI job outside Ravion. ## Get help -[Contact support](/contact-support) for anything this page does not cover: a lock that survives an unlock, a run that stays active for hours with no output, or a plan that reports resources as missing after you release a lock. Include the stack ID and the output of `ravion stack lock`. +[Contact support](/contact-support) for anything this page does not resolve, including a lock that survives an unlock, a run that stays active without producing output, or a plan that reports missing resources after a release. Include the stack ID and the output of `ravion stack lock`. From 6edd8e25cab9236a5aa59a0edae2083d305460d8 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 14:58:06 +0530 Subject: [PATCH 05/10] Regenerate stack CLI reference for the reworded force flag --- cli/reference/stack.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/reference/stack.mdx b/cli/reference/stack.mdx index 9d1a05e..fa457a9 100644 --- a/cli/reference/stack.mdx +++ b/cli/reference/stack.mdx @@ -105,6 +105,6 @@ ravion stack unlock [flags] | Flag | Required | Description | | --- | --- | --- | -| `--force` | | Release the lock even while a run is still active on the stack. Use when the run itself is stuck: the running Terraform keeps operating on state Ravion has stopped tracking for it, and its state write is discarded. | +| `--force` | | Release the lock while a run is still active on the stack. This covers a run that never completes and does not respond to cancellation, which is not expected behaviour. The run continues: Terraform still executing operates on state Ravion has stopped tracking for that run, and the state it writes is discarded. Cancel the run first whenever cancellation succeeds. | | `--json` | | emit response as JSON | From d4c22a32fd68f1111bcf389f1ce35818448524a7 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 19:12:01 +0530 Subject: [PATCH 06/10] Show the real lock payload the cloud backend records --- troubleshooting/stuck-terraform-state-lock.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/troubleshooting/stuck-terraform-state-lock.mdx b/troubleshooting/stuck-terraform-state-lock.mdx index dd9f15a..c2c304c 100644 --- a/troubleshooting/stuck-terraform-state-lock.mdx +++ b/troubleshooting/stuck-terraform-state-lock.mdx @@ -14,9 +14,9 @@ Error: Error acquiring the state lock Error message: workspace already locked Lock Info: - ID: 6a1c1e0c-... - Operation: OperationTypeApply - Who: root@ip-10-0-1-23 + ID: lock_1785936163253230000 + Operation: lock + Info: Locked by OpenTofu Created: 2026-08-04 18:22:41 UTC ``` From affb961fed657fb57ab1060f19f62899edbb99ef Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 19:31:52 +0530 Subject: [PATCH 07/10] Document the confirmation on a forced unlock --- cli/reference/stack.mdx | 1 + troubleshooting/stuck-terraform-state-lock.mdx | 2 ++ 2 files changed, 3 insertions(+) diff --git a/cli/reference/stack.mdx b/cli/reference/stack.mdx index fa457a9..9d90ac2 100644 --- a/cli/reference/stack.mdx +++ b/cli/reference/stack.mdx @@ -107,4 +107,5 @@ ravion stack unlock [flags] | --- | --- | --- | | `--force` | | Release the lock while a run is still active on the stack. This covers a run that never completes and does not respond to cancellation, which is not expected behaviour. The run continues: Terraform still executing operates on state Ravion has stopped tracking for that run, and the state it writes is discarded. Cancel the run first whenever cancellation succeeds. | | `--json` | | emit response as JSON | +| `-y, --yes` | | skip confirmation prompt | diff --git a/troubleshooting/stuck-terraform-state-lock.mdx b/troubleshooting/stuck-terraform-state-lock.mdx index c2c304c..e4ffce6 100644 --- a/troubleshooting/stuck-terraform-state-lock.mdx +++ b/troubleshooting/stuck-terraform-state-lock.mdx @@ -86,6 +86,8 @@ Such a run continues to hold the lock, and a standard unlock stays rejected. `-- ravion stack unlock --force ``` +The command states what releasing costs and asks you to confirm. Pass `--yes` alongside it to skip the prompt in a script. + Use `--force` only in this situation. The run itself continues: Terraform still executing operates on state that Ravion has stopped tracking for that run, and the state it writes is discarded. Cancel the run first whenever cancellation succeeds. `--force` is unavailable in the dashboard. The **Unlock stack** button requires every run to be inactive, which keeps forcing a deliberate action taken through the CLI or the API. From c542e9f337184f4b1cff90b637f0e8403a7e8099 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 20:35:26 +0530 Subject: [PATCH 08/10] Describe unlocking by what it actually costs --- cli/reference/stack.mdx | 2 +- troubleshooting/stuck-terraform-state-lock.mdx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/reference/stack.mdx b/cli/reference/stack.mdx index 9d90ac2..97d9d7f 100644 --- a/cli/reference/stack.mdx +++ b/cli/reference/stack.mdx @@ -105,7 +105,7 @@ ravion stack unlock [flags] | Flag | Required | Description | | --- | --- | --- | -| `--force` | | Release the lock while a run is still active on the stack. This covers a run that never completes and does not respond to cancellation, which is not expected behaviour. The run continues: Terraform still executing operates on state Ravion has stopped tracking for that run, and the state it writes is discarded. Cancel the run first whenever cancellation succeeds. | +| `--force` | | Release the lock while a run is still active on the stack. This covers a run that never completes and does not respond to cancellation, which is not expected behaviour. That run keeps going, and its state write is refused once the lock is gone, so the run fails and any cloud resources it already changed go unrecorded. State from completed operations is untouched. Cancel the run first whenever cancellation succeeds. | | `--json` | | emit response as JSON | | `-y, --yes` | | skip confirmation prompt | diff --git a/troubleshooting/stuck-terraform-state-lock.mdx b/troubleshooting/stuck-terraform-state-lock.mdx index e4ffce6..1cb9943 100644 --- a/troubleshooting/stuck-terraform-state-lock.mdx +++ b/troubleshooting/stuck-terraform-state-lock.mdx @@ -88,15 +88,15 @@ ravion stack unlock --force The command states what releasing costs and asks you to confirm. Pass `--yes` alongside it to skip the prompt in a script. -Use `--force` only in this situation. The run itself continues: Terraform still executing operates on state that Ravion has stopped tracking for that run, and the state it writes is discarded. Cancel the run first whenever cancellation succeeds. +Use `--force` only in this situation. The run keeps going, and its state write is refused once the lock is gone, so the run fails and any cloud resources it already changed go unrecorded. Cancel the run first whenever cancellation succeeds. `--force` is unavailable in the dashboard. The **Unlock stack** button requires every run to be inactive, which keeps forcing a deliberate action taken through the CLI or the API. ## What unlocking changes -Releasing the lock discards the state that the interrupted run had begun writing. The stack's state remains as it was after the last completed operation. +Releasing the lock discards a state write that the interrupted run had reserved and never finished. State from completed operations is untouched: Ravion keeps every finalized version, and the stack still points at the same current state. A lock left behind by a run that died before writing anything costs you nothing at all. -Your infrastructure can be ahead of that state. An apply that stopped partway can create resources that the state never recorded. Run a plan after unlocking and review it before applying: Terraform proposes creating every resource missing from the state. +The gap to watch is your real infrastructure. An apply that stopped partway can create resources that the state never recorded. Run a plan after unlocking and review it before applying: Terraform proposes creating every resource missing from the state. ## Locks that reappear From f8abe8f9f400e72307e95b9e43b50dedcd285b55 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 21:41:03 +0530 Subject: [PATCH 09/10] Correct which runs hold the state lock and rename get-lock --- cli/reference/stack.mdx | 22 +++++++++---------- .../stuck-terraform-state-lock.mdx | 12 +++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cli/reference/stack.mdx b/cli/reference/stack.mdx index 97d9d7f..bce4b2b 100644 --- a/cli/reference/stack.mdx +++ b/cli/reference/stack.mdx @@ -28,38 +28,38 @@ ravion stack get [flags] | --- | --- | --- | | `--json` | | emit response as JSON | -### `ravion stack list` +### `ravion stack get-lock` -List Stacks +Read a stack's Terraform state lock ```bash -ravion stack list [flags] +ravion stack get-lock [flags] ``` **Flags:** | Flag | Required | Description | | --- | --- | --- | -| `--cursor ` | | cursor | -| `--environment-id ` | | environmentId | | `--json` | | emit response as JSON | -| `--limit ` | | limit | -| `--project-id ` | | projectId | -| `-v, --verbose` | | show full output | -### `ravion stack lock` +### `ravion stack list` -Read a stack's Terraform state lock +List Stacks ```bash -ravion stack lock [flags] +ravion stack list [flags] ``` **Flags:** | Flag | Required | Description | | --- | --- | --- | +| `--cursor ` | | cursor | +| `--environment-id ` | | environmentId | | `--json` | | emit response as JSON | +| `--limit ` | | limit | +| `--project-id ` | | projectId | +| `-v, --verbose` | | show full output | ### `ravion stack resource-count` diff --git a/troubleshooting/stuck-terraform-state-lock.mdx b/troubleshooting/stuck-terraform-state-lock.mdx index 1cb9943..7f50c1d 100644 --- a/troubleshooting/stuck-terraform-state-lock.mdx +++ b/troubleshooting/stuck-terraform-state-lock.mdx @@ -24,9 +24,9 @@ This is a stuck lock. Releasing it allows the stack to run again. ## Confirm the lock is stuck -An active run holds its lock for a reason, and unlocking during a run discards work in progress. +A run holds the lock only while a Terraform operation is executing. Each `plan` and each `apply` takes the lock and releases it as that operation finishes, so a queued run holds nothing, and neither does a run paused for approval between its plan and its apply. -Open the stack and review its runs. Runs that are queued, in progress, or awaiting approval still hold their lock. Wait for them to complete, or cancel them. Ravion enforces this: an unlock during an active run is rejected and reports which run holds the lock. +Open the stack and review its runs. Wait for a running operation to finish, or cancel it. Ravion enforces this for you, and takes the cautious line: an unlock is rejected while any run on the stack is active, naming the run that blocks it. Ravion can release locks only for stacks that store their Terraform state in Ravion — those that @@ -50,7 +50,7 @@ Open the stack and review its runs. Runs that are queued, in progress, or awaiti Review the lock: ```bash - ravion stack lock + ravion stack get-lock ``` Release it: @@ -78,9 +78,9 @@ Open the stack and review its runs. Runs that are queued, in progress, or awaiti ## Runs that never complete -Every run reaches a final state, including runs that fail. A run that stays queued or in progress and does not respond to cancellation indicates a problem beyond the stack itself. This is not expected behaviour — [contact support](/contact-support) when you encounter it. +Every run reaches a final state, including runs that fail. A run that stays in progress and does not respond to cancellation indicates a problem beyond the stack itself. This is not expected behaviour — [contact support](/contact-support) when you encounter it. -Such a run continues to hold the lock, and a standard unlock stays rejected. `--force` releases the lock regardless of run status: +Such a run keeps hold of the lock, and a standard unlock stays rejected. `--force` releases the lock regardless of run status: ```bash ravion stack unlock --force @@ -104,4 +104,4 @@ A lock that returns immediately after release is held by an active process. Revi ## Get help -[Contact support](/contact-support) for anything this page does not resolve, including a lock that survives an unlock, a run that stays active without producing output, or a plan that reports missing resources after a release. Include the stack ID and the output of `ravion stack lock`. +[Contact support](/contact-support) for anything this page does not resolve, including a lock that survives an unlock, a run that stays active without producing output, or a plan that reports missing resources after a release. Include the stack ID and the output of `ravion stack get-lock`. From db8ee060a1d8a1f869da72338b5da6ec126c46d9 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Wed, 5 Aug 2026 23:47:40 +0530 Subject: [PATCH 10/10] Apply suggestion from @siddhsuresh --- troubleshooting/stuck-terraform-state-lock.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshooting/stuck-terraform-state-lock.mdx b/troubleshooting/stuck-terraform-state-lock.mdx index 7f50c1d..3df8ed3 100644 --- a/troubleshooting/stuck-terraform-state-lock.mdx +++ b/troubleshooting/stuck-terraform-state-lock.mdx @@ -24,7 +24,7 @@ This is a stuck lock. Releasing it allows the stack to run again. ## Confirm the lock is stuck -A run holds the lock only while a Terraform operation is executing. Each `plan` and each `apply` takes the lock and releases it as that operation finishes, so a queued run holds nothing, and neither does a run paused for approval between its plan and its apply. +A run holds the lock only while a Terraform operation is executing. Each `plan` and each `apply` takes the lock and releases it as that operation finishes. Open the stack and review its runs. Wait for a running operation to finish, or cancel it. Ravion enforces this for you, and takes the cautious line: an unlock is rejected while any run on the stack is active, naming the run that blocks it.