Skip to main content
FlowPilot tracks two different version numbers. Keeping them straight avoids confusion when you read a flow or debug a resolve response.

Two version counters

CounterWhere it livesCurrent valuePurpose
Content/migration versionThe version field inside the flow JSON (CURRENT_SCHEMA_VERSION in the editor)8Tracks editor-side schema shape changes. Old flows migrate forward to this on load.
Wire format versionThe schema_version field on a flow version (and in the resolve response)1The compatibility gate the SDK checks. A major bump means the wire format changed.
The content version is bumped by the editor’s migrations as the component model evolves. The wire format version stays at 1 because the on-the-wire JSON shape the SDK parses has not changed in a way that breaks older SDKs. They are not the same number, and that is expected.

Editor migrations (content version)

When the editor loads a flow whose version is below 8, it applies migrations in sequence until it reaches the current version. Each migration is small and runs on load (never on save unless you then save the draft).
FromToWhat it does
12Rename Chrome to Persistent UI zones (Navigation Bar, Footer, Overlay).
23Merge checkbox into toggle as a variant.
34Strip removed component nodes (carousel, video, lottie, chart, spacer, divider).
45Unwind the checkbox toggle-variant: re-ship checkbox as a Block (stack + icon + text).
56Unify the button’s style surface with the stack’s (canonical justify/align/padding/cornerRadius/width/spacing/text/color).
67Collapse the card primitive into a styled stack (surface defaults merged).
78Collapse the chip primitive into a styled stack (capsule + text child + onPress selection).
If a flow is somehow ahead of the migration registry (no migration path found), the editor logs a warning and stamps it as the current version without transforming it.

Removed and rewritten types

Migrations strip or rewrite types that are no longer in the schema:
  • Stripped from the layout tree on load: carousel, video, chart, spacer, divider (and the old placeholder lottie). The parent stays; only the removed node and its descendants go.
  • Rewritten into a composition of current primitives: checkbox and chip become styled stacks; card becomes a styled stack with surface defaults; legacy button-only prop names map to the canonical ones.
lottie and comparisonChart are supported component kinds in the current schema. The strip in the 3 to 4 migration applied to the earlier placeholder versions of these kinds; the real primitives were added later. See the Component reference for the current list.

SDK compatibility (wire format version)

The iOS SDK checks the resolve response’s schema_version against the highest version it supports (1.0.0 in the current SDK). It compares the major component only.
  • Same major version: the flow renders. If the minor or patch is newer than the SDK, the SDK renders best-effort and logs a warning. Any component or node type the build does not recognize is skipped rather than failing the whole screen.
  • Higher major version: the SDK throws unsupportedSchemaVersion with the message “Flow requires schema X, but SDK only supports up to Y. Please update the app.” This is the signal that the wire format changed in a way the installed SDK genuinely cannot parse.
This is why additive changes (new component kinds, new props) are safe for old apps: they fall under the same major version and are skipped if unknown. A major bump is reserved for breaking format changes and would require an app update. unsupportedSchemaVersion is one of the error codes the SDK can surface. With the never-throwing fallback overloads it is delivered as a FlowResult error rather than thrown.

Notes

  • The migration chain is what lets you publish over many months without breaking old drafts: opening an old flow upgrades it in the editor.
  • The exact per-version field-level changes beyond the descriptions above are not enumerated here; the migration descriptions above are taken verbatim from the migration registry.