{"record":{"id":"45c02ae092a2472a","repo":"hashicorp/terraform","slug":"can-t-ask-approval-for-state-migration-when-intera","errorCode":null,"errorMessage":"Can't ask approval for state migration when interactive input is disabled.\n\nPlease remove the \"-input=false\" option and try again.","messagePattern":"Can't ask approval for state migration when interactive input is disabled\\.\n\nPlease remove the \"-input=false\" option and try again\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/meta_backend_migrate.go","lineNumber":437,"sourceCode":"\t\t\tconfirmFunc = m.backendMigrateEmptyConfirm\n\t\t}\n\n\t// Both states are non-empty, meaning we need to determine which\n\t// state should be used and update accordingly.\n\tcase !source.Empty() && !destination.Empty():\n\t\tlog.Print(\"[TRACE] backendMigrateState: both source and destination workspaces have states, so might overwrite destination with source\")\n\t\tconfirmFunc = m.backendMigrateNonEmptyConfirm\n\t}\n\n\tif confirmFunc == nil {\n\t\tpanic(\"confirmFunc must not be nil\")\n\t}\n\n\tif !opts.force {\n\t\t// Abort if we can't ask for input.\n\t\tif !m.input {\n\t\t\tlog.Print(\"[TRACE] backendMigrateState: can't prompt for input, so aborting migration\")\n\t\t\treturn errors.New(strings.TrimSpace(errInteractiveInputDisabled))\n\t\t}\n\n\t\t// Confirm with the user whether we want to copy state over\n\t\tconfirm, err := confirmFunc(sourceState, destinationState, opts)\n\t\tif err != nil {\n\t\t\tlog.Print(\"[TRACE] backendMigrateState: error reading input, so aborting migration\")\n\t\t\treturn err\n\t\t}\n\t\tif !confirm {\n\t\t\tlog.Print(\"[TRACE] backendMigrateState: user cancelled at confirmation prompt, so aborting migration\")\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// Confirmed! We'll have the statemgr package handle the migration, which\n\t// includes preserving any lineage/serial information where possible, if\n\t// both managers support such metadata.\n\tlog.Print(\"[TRACE] backendMigrateState: migration confirmed, so migrating\")","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/command/meta_backend_migrate.go#L419-L455","documentation":"Returned by backendMigrateState (meta_backend_migrate.go:437) — the generic state-migration confirmation path. When opts.force is false the code must ask the user to approve copying/overwriting state, but if m.input is false (input disabled) it cannot prompt and returns errInteractiveInputDisabled. This covers both the empty-destination and non-empty-destination confirm cases (backendMigrateEmptyConfirm / backendMigrateNonEmptyConfirm).","triggerScenarios":"Running `terraform init -migrate-state` (or changing the backend block and running init) with -input=false, where the source has state that needs approval to copy/overwrite into the destination.","commonSituations":"Switching backend type (e.g. local -> s3, s3 -> local, s3 -> another s3 bucket) in CI with -input=false; the destination already has state so overwrite approval is required.","solutions":["Remove -input=false and run `terraform init -migrate-state` interactively to answer the prompt.","Use `-migrate-state -force-copy` (force=true) to skip the confirmation when input is disabled.","If you do not want migration, run `terraform init -reconfigure` to discard the previous backend state instead of migrating."],"exampleFix":"# before\n terraform init -input=false -migrate-state\n# after (auto-approve the copy)\n terraform init -input=false -migrate-state -force-copy","handlingStrategy":"validation","validationCode":"// Before `terraform init -migrate-state` non-interactively, decide the copy policy.\n if nonInteractive {\n     args = append(args, \"-force-copy\") // skip confirmFunc approval\n }","typeGuard":null,"tryCatchPattern":"out, err := exec.Command(\"terraform\", \"init\", \"-input=false\", \"-migrate-state\").CombinedOutput()\n if err != nil && bytes.Contains(out, []byte(\"interactive input is disabled\")) {\n     // retry with -force-copy (or run interactively)\n     exec.Command(\"terraform\", \"init\", \"-input=false\", \"-migrate-state\", \"-force-copy\").Run()\n }","preventionTips":["Pair -migrate-state with -force-copy whenever you run with -input=false in automation.","Prefer `terraform init -reconfigure` when you do not actually need to migrate state."],"tags":["backend","state-migration","input","non-interactive","init"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}