Skip to content

List valid actions in invalid_state errors#228

Closed
sjmiller609 wants to merge 2 commits into
mainfrom
hypeship/restore-error-valid-states
Closed

List valid actions in invalid_state errors#228
sjmiller609 wants to merge 2 commits into
mainfrom
hypeship/restore-error-valid-states

Conversation

@sjmiller609
Copy link
Copy Markdown
Collaborator

@sjmiller609 sjmiller609 commented May 11, 2026

Summary

Caller hit `invalid state transition: cannot restore from state Paused` and had no way to know what they were allowed to do instead. Now every caller-facing `ErrInvalidState` message names the current state and the user-facing API actions valid from it.

Before:
```
invalid state transition: cannot restore from state Paused
invalid state transition: cannot start from state Running, must be Stopped
invalid state transition: stopped snapshot requires source in Stopped, got Running
```

After:
```
invalid state transition: cannot restore from state Paused (no actions valid from this state)
invalid state transition: cannot start from state Running, valid actions from Running: stop, standby, snapshot, fork (with from_running=true), update
invalid state transition: cannot snapshot from state Running, valid actions from Running: stop, standby, snapshot, fork (with from_running=true), update
```

Approach

  • New `State.UserActions()` returns the user-facing verbs callable from a given state. Backed by a single map so the matrix lives in one place.
  • New `NewInvalidStateError(action, state)` constructs an `ErrInvalidState` with the attempted action, current state, and the action list.
  • Routed all caller-facing state-rejection sites through the helper: `start`, `stop`, `standby`, `restore`, `fork` (3 sites), `snapshot` (3 sites incl. `restore_snapshot` and the scheduler), `update env`.
  • Kept the `fork` "set from_running=true" hint on the specific Running-without-flag case by wrapping the helper output.
  • Updated the OpenAPI example for snapshot-schedule `last_error` to match the new format.

Test plan

  • Hit each rejected path (e.g. restore from Paused, start from Running, snapshot from Paused) and confirm the response message lists the actions valid from the current state.

Every caller-facing ErrInvalidState now names the current state and the
user-facing API actions that are valid from it, e.g.:

  cannot restore from state Paused (no actions valid from this state)
  cannot start from state Running, valid actions from Running: stop,
  standby, snapshot, fork (with from_running=true), update

Adds State.UserActions and NewInvalidStateError helpers in state.go and
routes start/stop/standby/restore/fork/snapshot/restore_snapshot/update
and the scheduled-snapshot path through them.
@sjmiller609 sjmiller609 changed the title Include valid state in restore error message List valid actions in invalid_state errors May 11, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 11, 2026

✱ Stainless preview builds for hypeman

This PR will update the hypeman SDKs with the following commit message.

feat: Include valid state in restore error message

Edit this comment to update it. It will appear in the SDK's changelogs.

hypeman-typescript studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅build ⏭️ (prev: build ✅) → lint ⏭️ (prev: lint ❗) → test ✅

hypeman-go studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅build ⏭️ (prev: build ✅) → lint ✅test ✅

go get github.com/stainless-sdks/hypeman-go@a0ea56dcc08b0d80e9c142f0ee160441d28b6c39
hypeman-openapi studio · code · diff

Your SDK build had at least one "note" diagnostic, but this did not represent a regression.
generate ✅


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-05-11 21:09:27 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant