{"record":{"id":"d6e134f1374984c7","repo":"appsmithorg/appsmith","slug":"backup-process-aborted-because-a-valid-encryption","errorCode":null,"errorMessage":"Backup process aborted because a valid encryption password could not be obtained from the user","messagePattern":"Backup process aborted because a valid encryption password could not be obtained from the user","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/client/packages/rts/src/ctl/backup/links/EncryptionLink.ts","lineNumber":79,"sourceCode":"\n    if (encryptionPwd1 === encryptionPwd2) {\n      if (encryptionPwd1) {\n        return encryptionPwd1;\n      }\n\n      console.error(\n        \"Invalid input. Empty password is not allowed, please try again.\",\n      );\n    } else {\n      console.error(\"The passwords do not match, please try again.\");\n    }\n  }\n\n  console.error(\n    \"Aborting backup process, failed to obtain valid encryption password.\",\n  );\n\n  throw new Error(\n    \"Backup process aborted because a valid encryption password could not be obtained from the user\",\n  );\n}\n\nexport async function encryptBackupArchive(\n  archivePath: string,\n  encryptionPassword: string,\n) {\n  const encryptedArchivePath = archivePath + \".enc\";\n\n  await utils.execCommand([\n    \"openssl\",\n    \"enc\",\n    \"-aes-256-cbc\",\n    \"-pbkdf2\",\n    \"-iter\",\n    \"100000\",\n    \"-in\",","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/appsmithorg/appsmith/blob/8cd9021c24cdbea1c3c12c966073708e83db60c2/app/client/packages/rts/src/ctl/backup/links/EncryptionLink.ts#L61-L97","documentation":"Thrown by the EncryptionLink after its interactive prompt loop exhausts without a valid password. The loop rejects an empty password and rejects non-matching confirmations; on exit it logs an abort message and throws, stopping the backup-encryption step so a backup is never written without a usable encryption password.","triggerScenarios":"Running an encrypted backup where the operator, when prompted twice for a password and confirmation, supplies an empty value or two non-matching values repeatedly until the prompt loop gives up.","commonSituations":"Non-interactive/CI run where stdin has no TTY so prompts read EOF; operator typing mismatched confirmation; paste of a password with trailing newline differences; automation invoking the ctl without piping a password.","solutions":["Provide a matching, non-empty password and confirmation when prompted.","For automation, pipe the password from a secure source using a tty-creating wrapper (e.g. 'script' or 'expect') so the prompt loop receives matching input.","Verify caps-lock / keyboard layout if confirmations keep mismatching interactively.","If the flow must run non-interactively, check for an env/file-based password option in the EncryptionLink config and use it instead of the prompt."],"exampleFix":"# before (CI with no TTY -> prompt reads EOF, throws)\n$ appsmith backup create --encrypt\n\n# after\n$ printf '%s\\n%s\\n' \"$BACKUP_PASS\" \"$BACKUP_PASS\" | script -qc 'appsmith backup create --encrypt' /dev/null","handlingStrategy":"validation","validationCode":"function isValidPasswordPair(p: string, confirm: string) {\n  return Boolean(p) && p === confirm;\n}","typeGuard":"const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;","tryCatchPattern":"try { await runEncryptedBackup(); } catch (e) {\n  if (/encryption password/i.test(e.message)) { /* surface a non-interactive password source */ }\n  else throw e;\n}","preventionTips":["Provide matching, non-empty passwords in interactive prompts.","For automation, pipe credentials via a TTY-creating wrapper.","Avoid pasting passwords with trailing newlines that mismatch the confirmation."],"tags":["backup","encryption","interactive","rts","operations"],"backgroundTag":null,"analyzedSha":"8cd9021c24cdbea1c3c12c966073708e83db60c2","analyzedAt":"2026-08-12T22:14:19.293Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}