{"record":{"id":"9cc010491156e49a","repo":"hashicorp/terraform","slug":"migration-aborted-by-user","errorCode":null,"errorMessage":"Migration aborted by user.","messagePattern":"Migration aborted by user\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/meta_backend_migrate.go","lineNumber":190,"sourceCode":"\tif !migrate {\n\t\tvar err error\n\t\t// Ask the user if they want to migrate their existing remote state\n\t\tmigrate, err = m.confirm(&terraform.InputOpts{\n\t\t\tId: \"backend-migrate-multistate-to-multistate\",\n\t\t\tQuery: fmt.Sprintf(\n\t\t\t\t\"Do you want to migrate all workspaces to %s %q?\",\n\t\t\t\tdstWord, opts.DestinationType),\n\t\t\tDescription: fmt.Sprintf(\n\t\t\t\tstrings.TrimSpace(inputBackendMigrateMultiToMulti),\n\t\t\t\topts.SourceType, srcWord, opts.DestinationType, dstWord),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"Error asking for state migration action: %s\", err)\n\t\t}\n\t}\n\tif !migrate {\n\t\treturn fmt.Errorf(\"Migration aborted by user.\")\n\t}\n\n\t// Read all the states\n\tsourceWorkspaces, wDiags := opts.Source.Workspaces()\n\tif wDiags.HasErrors() {\n\t\treturn fmt.Errorf(strings.TrimSpace(\n\t\t\terrMigrateLoadStates), opts.SourceType, srcWord, wDiags.Err())\n\t}\n\tif wDiags.HasWarnings() {\n\t\tlog.Printf(\"[WARN] backendMigrateState_S_S: warning(s) returned when getting workspaces from source backend: %s\", wDiags.ErrWithWarnings())\n\t}\n\n\t// Sort the states so they're always copied alphabetically\n\tsort.Strings(sourceWorkspaces)\n\n\t// Go through each and migrate\n\tfor _, name := range sourceWorkspaces {\n\t\t// Copy the same names","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/meta_backend_migrate.go#L172-L208","documentation":"Returned in the multi-state-to-multi-state migration when the user is asked to confirm migrating all workspaces and answers in the negative (or `opts.force` is false and `migrate` resolves false). It is an explicit user-initiated abort, not a system failure.","triggerScenarios":"Fires in `backendMigrateState_S_S` after the `backend-migrate-multistate-to-multistate` prompt returns successfully but with a value that is not truthy (e.g. the user types `no` or `n`).","commonSituations":"A developer re-runs `terraform init` after editing the backend and chooses not to migrate, or an automated harness that auto-answers `no` to all prompts.","solutions":["Re-run init and answer `yes` to the migration prompt.","Use `-migrate-state=true` to skip the prompt and proceed with migration.","If you genuinely do not want migration, use `-migrate-state=false` and accept that the destination backend starts empty."],"exampleFix":"# before\nterraform init   # answered 'no'\n# after\nterraform init -migrate-state=true","handlingStrategy":"validation","validationCode":"# Express migration intent as a CI variable so the prompt never blocks.\nMIGRATE=${MIGRATE_STATE:-true}\nterraform init -input=false -migrate-state=$MIGRATE","typeGuard":null,"tryCatchPattern":"# A user 'no' is a decision, not a failure — surface it distinctly:\nif terraform init 2>&1 | tee /tmp/init.log; then :; else\n  if grep -q 'Migration aborted by user' /tmp/init.log; then\n    echo \"Migration declined by operator; investigate intent\" >&2; exit 3\n  fi\nfi","preventionTips":["Use -migrate-state=true to make 'yes' the default in automation.","Train operators that 'no' aborts the whole init, not just migration.","Document the backend change that triggers the prompt so the answer is intentional."],"tags":["backend","migration","multi-state","user-abort","init"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}