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

# Recovery

> Diagnosing and recovering from failures in virtual mode.

Virtual mode has explicit recovery paths for common failure scenarios. SQLBuild blocks cleanly rather than leaving ambiguous state, and error messages point to the specific recovery action needed.

## State corruption

| Scenario                            | Error                                                   | Recovery                                               |
| ----------------------------------- | ------------------------------------------------------- | ------------------------------------------------------ |
| Missing state table                 | "Cannot backup invalid state schema" on `state migrate` | `sqb state reset --auto-approve` then `sqb state init` |
| Missing state column                | Same                                                    | Same                                                   |
| Wrong state column type             | Same                                                    | Same                                                   |
| Deleted backup schema (explicit id) | Rollback blocks with backup-id error                    | Use a different backup or reset                        |
| All backups deleted                 | "No state backup is available for rollback"             | `sqb state reset --auto-approve` then reinitialize     |

State corruption is detected by schema validation during `state migrate`. If the current state schema is invalid, SQLBuild refuses to back it up (to avoid persisting a broken snapshot) and directs you to reset.

## Warehouse drift

| Scenario                              | Detection                                        | Recovery                                           |
| ------------------------------------- | ------------------------------------------------ | -------------------------------------------------- |
| Missing logical VDE view              | `sqb reconcile` reports missing view             | `sqb reconcile repair-view` for the affected model |
| Missing physical relation             | `sqb reconcile` reports it, `repair-view` blocks | Rebuild with `sqb build --select`                  |
| Logical target is a table, not a view | `repair-view` and `attach` block                 | Drop the table manually, then `repair-view`        |
| Checkpoint physical relation missing  | `sqb rollback` blocks                            | Use a more recent checkpoint, or rebuild           |
| Promoted physical relation missing    | `sqb promote` blocks                             | Rebuild the source VDE first                       |

## Lock conflicts

| Scenario                      | Error                           | Recovery                                      |
| ----------------------------- | ------------------------------- | --------------------------------------------- |
| VDE locked by another process | "virtual environment is locked" | Wait for the other process, or clear the lock |
| Lock held by crashed process  | Same                            | `sqb state locks clear` with `--force`        |

Only clear locks when you are certain the holding operation is no longer running.

## Interrupted operations

| Scenario              | Behavior                                                                    | Recovery                                                     |
| --------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------ |
| Interrupted adopt     | Failed operation recorded. Physical schema may have partial artifacts.      | `sqb reconcile` to diagnose, manual repair if needed, retry. |
| Interrupted detach    | Failed operation recorded. VDE stays finalized. Physical version preserved. | `sqb reconcile` to diagnose, retry detach.                   |
| Interrupted promotion | Failed operation recorded. Target VDE lock released.                        | Retry promote.                                               |

There is no automatic resume command for interrupted operations. SQLBuild records the failure in `state_operations` and `state_operation_events`, preserves VDE refs and checkpoints, and leaves recovery to the operator.

To inspect a failed operation:

```sql theme={null}
SELECT operation_id, operation_type, status, virtual_environment_name
FROM sqlbuild_state.state_operations
WHERE status = 'failed';

SELECT operation_id, action, status, message
FROM sqlbuild_state.state_operation_events
WHERE operation_id = '<id>'
ORDER BY created_at;
```

## Mode guards

SQLBuild blocks operations that don't apply to the current mode:

| Operation                          | Direct mode | Virtual mode                                  |
| ---------------------------------- | ----------- | --------------------------------------------- |
| `sqb state` subcommands            | Blocked     | Allowed                                       |
| `sqb build --no-tests --no-audits` | Allowed     | Blocked (use `sqb build`)                     |
| `sqb build --defer-to`             | Allowed     | Blocked (VDE refs handle upstream resolution) |
| `sqb promote`                      | Blocked     | Allowed                                       |
| `sqb rollback`                     | Blocked     | Allowed                                       |
| `sqb reconcile`                    | Blocked     | Allowed                                       |

## Detached VDE guards

After `sqb state detach`, the VDE is marked `detached` and blocked from further virtual operations:

| Operation                       | Behavior                                  |
| ------------------------------- | ----------------------------------------- |
| `sqb build`                     | Blocks: "virtual environment is detached" |
| `sqb promote --from <detached>` | Blocks                                    |
| `sqb promote --to <detached>`   | Blocks                                    |
| `sqb rollback`                  | Blocks                                    |

The project can continue in standard mode or re-adopt to return to virtual mode.

## Adopt guards

| Condition                                   | Error                       |
| ------------------------------------------- | --------------------------- |
| No `unsuffixed_virtual_env` configured      | Blocks with config guidance |
| Copy fallback needed without `--allow-copy` | `requires --allow-copy`     |
| Wrong typed confirmation                    | Cancelled, no changes made  |

## Detach guards

| Condition                                   | Error                                      |
| ------------------------------------------- | ------------------------------------------ |
| VDE not finalized                           | "requires a finalized virtual environment" |
| Copy fallback needed without `--allow-copy` | `requires --allow-copy`                    |
| Wrong typed confirmation                    | Cancelled, no changes made                 |

## General recovery strategy

1. **Diagnose** with `sqb reconcile` or by querying state tables directly
2. **Repair views** with `sqb reconcile repair-view` for missing/broken logical views
3. **Rebuild** with `sqb build --select <model>` for missing physical versions
4. **Roll back** with `sqb rollback` to restore a prior finalized state
5. **Reset state** with `sqb state reset --auto-approve` as a last resort (drops all virtual state)

When in doubt, `sqb reconcile` is the starting point. It reports what's wrong without changing anything.
