sb-mig
Reference

migrate

Run content and preset migration pipelines.

migrate

sb-mig migrate content --all --from <space> --to <space> --migration <name>
sb-mig migrate presets --all --from <space-or-file> --to <space> --migration <name>
sb-mig migrate continue

migrate loads local migration config files, applies them in memory, writes artifacts, and then writes changed stories or presets unless --dry-run is passed. migrate continue finishes a previous --dry-run by replaying its saved result to Storyblok without re-running the preparation phase.

Shared flags

Exact flag names on this page include fromFilePath, migrationComponentAlias, migrationComponents, withSlug, startsWith, publicationMode, publicationLanguages, languagePublishStatePath, and fileName.

FlagTypeApplies toEffect
--fromstringcontent, presetsSource space ID. With --migrate-from file, it can be a local backup file name.
--fromFilePathstringcontent, presetsDirect path to a stories or presets JSON file when --migrate-from file is used.
--tostringcontent, presetsTarget Storyblok space ID.
--migrate-fromspace or filecontent, presetsRead source items from Storyblok or local JSON. Default: space.
--migrationrepeatable stringcontent, presetsMigration config name without extension. Content supports multiple ordered values. Presets support one value.
--migrationComponentAliasrepeatable stringcontent, presetsAdd mapper aliases. Format: <migration>:<source>=<alias1>,<alias2>.
--migrationComponentsrepeatable stringcontent, presetsOverride exact component scope. Format: <migration>:<component1>,<component2>.
--dry-runbooleancontent, presetsApply migration in memory and write artifacts without Storyblok writes.
--fileNamestringcontent, presetsStable artifact base name. Also disables datestamped artifact names.
--yesbooleancontent, presetsSkip confirmation prompt for real writes.

content

Primary form

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration migration-name \
  --dry-run

--all means "select all non-folder stories, then run the component mappers defined by the migration config." It does not mean every component must change. Only stories whose JSON changes are written to the *-to-migrate artifact and, in real runs, to Storyblok.

Content-only flags

FlagTypeEffect
--allbooleanSelect all non-folder stories in scope.
--withSlugrepeatable stringSelect exact story full_slug values.
--startsWithstringSelect stories whose full_slug starts with the prefix.
--publicationModeenumpreserve-layers, collapse-draft, or save-only. Default: preserve-layers.
--publicationLanguagesstringdefault, all, or comma-separated language codes. Default for publishing modes: all.
--languagePublishStatePathstringReuse a JSON map generated by language-publish-state.

Story selection

Select all non-folder stories:

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration migration-name

Select exact slugs:

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration migration-name \
  --withSlug blog/home \
  --withSlug docs/getting-started

Select a subtree by prefix:

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration migration-name \
  --startsWith blog/

Scoped component migrations

Use --migrationComponents to restrict one migration to specific component names:

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration colorPickerModeValues \
  --migrationComponents colorPickerModeValues:sb-section,sb-tour-page-section

Use --migrationComponentAlias when another component should reuse an existing mapper:

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration colorPickerModeValues \
  --migrationComponentAlias colorPickerModeValues:sb-button=sb-open-drift-button

You can combine aliases and overrides. Alias first, then include the alias in the override list if you want the migration scoped to only those components:

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration colorPickerModeValues \
  --migrationComponentAlias colorPickerModeValues:sb-button=sb-open-drift-button \
  --migrationComponents colorPickerModeValues:sb-button,sb-open-drift-button

The help output currently lists sb-mig migrate content <component-name ...>. In 6.1.1-beta.1, the built CLI rejects that combination because the default migrateFrom flag is present during command matching. Use --all plus --migrationComponents for deterministic scoped migrations.

Multiple migration steps

Content migrations can run multiple configs in order:

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration migration-a \
  --migration migration-b \
  --migration migration-c \
  --yes

Each step gets its own pipeline summary entry. If a migration has a matching validator, the validator runs after that step.

File input

Read from a discovered local backup file name:

sb-mig migrate content --all \
  --migrate-from file \
  --from file-with-stories \
  --to 12345 \
  --migration migration-name

Read from an explicit file path:

sb-mig migrate content --all \
  --migrate-from file \
  --fromFilePath sbmig/migrations/dry-run--12345---story-to-migrate.json \
  --to 12345 \
  --migration migration-a \
  --migration migration-b

When --fromFilePath is used and --from is omitted, sb-mig derives the artifact base name from the file path.

Publication modes

ModeBehaviorConstraints
preserve-layersDefault. Migrates draft/current and latest published layer for dirty published stories, publishes the migrated published layer, then restores migrated draft/current.Requires --migrate-from space and --from equal to --to.
collapse-draftMigrates draft/current only. Published stories can be republished from the migrated draft/current layer. Dirty draft content becomes the published content.Works for duplicated-space workflows where preserving a separate published layer is not required.
save-onlySaves migrated draft/current content and never publishes.Cannot be combined with --publicationLanguages or --languagePublishStatePath.

Legacy flags are rejected:

Old flagReplacement
--publish--publicationMode preserve-layers or --publicationMode collapse-draft
--publishLanguages--publicationLanguages
--preservePublishedLayer--publicationMode preserve-layers

Publication languages

--publicationLanguages default
--publicationLanguages all
--publicationLanguages default,fr,de

default maps to Storyblok's default-language publish token. all resolves the target space languages and publishes [default] plus configured language codes.

When a publishing mode is active and --languagePublishStatePath is omitted, sb-mig builds a language publish-state map automatically for the selected stories. For sensitive runs, generate the map first:

sb-mig language-publish-state \
  --from 12345 \
  --startsWith blog/ \
  --languages all \
  --fileName blog-prod

sb-mig migrate content --all \
  --from 12345 \
  --to 12345 \
  --migration migration-name \
  --publicationMode preserve-layers \
  --publicationLanguages all \
  --languagePublishStatePath sbmig/language-publish-state/blog-prod.json \
  --yes

presets

Valid forms

sb-mig migrate presets --all \
  --from 12345 \
  --to 12345 \
  --migration preset-migration \
  --dry-run

sb-mig migrate presets --all \
  --migrate-from file \
  --fromFilePath sbmig/presets/presets-backup.json \
  --to 12345 \
  --migration preset-migration

Preset constraints

ConstraintReason
Exactly one --migration valuePreset migration pipelines do not support multiple ordered configs yet.
--publicationMode is rejectedPresets cannot be published.
--publicationLanguages is rejectedPresets cannot be published by language.
--languagePublishStatePath is rejectedPresets do not use story publish-state maps.

Before a real preset run, sb-mig backs up all remote presets to presets-backup.

continue

continue finishes a previous migrate content --dry-run by writing its already-computed result to Storyblok. It skips the expensive preparation a dry run already did — pulling stories, applying mappers in memory, and fetching published layers and language state — and replays only the writes. On large spaces this turns the "dry run, then real run" workflow from roughly double the cost into one preparation plus a fast write, so always running a dry run first no longer doubles the wait.

continue assumes a content freeze between the dry run and the continue run. The source space must not change in between: continue trusts the dry run's result and does not re-read or diff the space (no drift detection).

Primary form

sb-mig migrate continue

continue discovers the dry run's continue manifest in sbmig/migrations, prints a summary of what it will write (space, publication mode, languages, story counts, and the artifacts it will use), and prompts for confirmation before writing.

continue-only flags

FlagTypeEffect
--manifeststringContinue manifest filename inside sbmig/migrations. Only needed when more than one dry-run manifest is present.
--yesbooleanSkip the confirmation prompt for the write.

Manifest discovery

SituationBehavior
Exactly one continue manifest in sbmig/migrationsUsed automatically.
More than oneStops and lists them; pass --manifest <filename> to pick one.
NoneErrors and points you at migrate content … --dry-run.

Equivalent to a real run

continue writes exactly what a real migrate content would: it updates applied-backpack-migrations.json, performs the same Storyblok writes (including the preserve-layers dual-layer write for dirty published stories), and writes a migration run log tagged with the originating manifest.

It performs no bulk story fetch, no in-memory migration, no published-layer fetch, and no language-state fetch. The only read it still makes is the existing per-story safety re-fetch inside the preserve-layers dual-layer write.

Artifacts and side effects

For --migrate-from space real runs, sb-mig writes a pre-migration backup under sbmig/backup/story or sbmig/backup/preset.

All content and preset runs write migration artifacts under sbmig/migrations. Dry runs return before Storyblok writes. Real runs also write a JSONL migration run log after Storyblok write attempts complete.

A content dry run additionally writes a *-continue-manifest file (and, for preserve-layers, a *-dirty-published-records file) that migrate continue uses to replay the run. The dry run's *-input-full artifacts are the pre-migration snapshot for that workflow, since continue does not re-read the space to take its own backup.

On this page