{"record":{"id":"6d2cc4d5f0c56c02","repo":"apache/seatunnel","slug":"restore-and-restore-with-checkpoint-are-mutual","errorCode":null,"errorMessage":"--restore and --restore-with-checkpoint are mutually exclusive","messagePattern":"--restore and --restore-with-checkpoint are mutually exclusive","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-core/seatunnel-starter/src/main/java/org/apache/seatunnel/core/starter/seatunnel/args/ClientCommandArgs.java","lineNumber":170,"sourceCode":"            description = \"list job status\")\n    private boolean listJob = false;\n\n    @Parameter(\n            names = {\"--async\"},\n            description =\n                    \"Run the job asynchronously, when the job is submitted, the client will exit\")\n    private boolean async = false;\n\n    @Parameter(\n            names = {\"-cj\", \"--close\", \"--close-job\"},\n            description = \"Close client the task will also be closed\")\n    private boolean closeJob = true;\n\n    @Override\n    public Command<?> buildCommand() {\n        validateCommandOptions();\n        if (restoreJobId != null && restoreWithCheckpointJobId != null) {\n            throw new IllegalArgumentException(\n                    \"--restore and --restore-with-checkpoint are mutually exclusive\");\n        }\n        if (savePointJobId != null && restoreWithCheckpointJobId != null) {\n            throw new IllegalArgumentException(\n                    \"--savepoint and --restore-with-checkpoint are mutually exclusive\");\n        }\n        if (restoreWithCheckpointJobId != null) {\n            restoreWithCheckpointJobId =\n                    normalizeNumericJobId(\n                            restoreWithCheckpointJobId,\n                            \"restoreSourceJobId is required when using --restore-with-checkpoint\",\n                            \"--restore-with-checkpoint requires a numeric jobId, got: \");\n        }\n        if (customJobId != null) {\n            customJobId =\n                    normalizeNumericJobId(\n                            customJobId,\n                            \"--set-job-id requires a non-blank jobId\",","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-core/seatunnel-starter/src/main/java/org/apache/seatunnel/core/starter/seatunnel/args/ClientCommandArgs.java#L152-L188","documentation":"ClientCommandArgs.buildCommand validates CLI options before building the client command. Passing both --restore (restore from a saved state/savepoint) and --restore-with-checkpoint (restore from the latest checkpoint) is rejected, because a job can only be restored from one source. Thrown as IllegalArgumentException at argument-parsing time.","triggerScenarios":"Submitting a job with both --restore <jobId> and --restore-with-checkpoint <jobId> on the command line (or both set programmatically on ClientCommandArgs before buildCommand()).","commonSituations":"Script templating that unconditionally appends both flags; migrating scripts from --restore to the newer --restore-with-checkpoint while keeping the old flag; confusion between the two restore mechanisms.","solutions":["Remove one of the two flags; keep only the restore mechanism you want","Use --restore <jobId> to restore from a savepoint, or --restore-with-checkpoint <jobId> to restore from the latest checkpoint — not both","Update wrapper scripts to emit exactly one restore flag"],"exampleFix":"// before\n--restore 12345 --restore-with-checkpoint 12345\n// after\n--restore-with-checkpoint 12345","handlingStrategy":"validation","validationCode":"if (args.has(\"restore\") && args.has(\"restore-with-checkpoint\")) {\n    throw new IllegalArgumentException(\"pass only one of --restore / --restore-with-checkpoint\");\n}","typeGuard":"boolean hasConflictingRestoreFlags(String[] cliArgs) {\n    boolean r = false, rc = false;\n    for (String a : cliArgs) {\n        if (a.startsWith(\"--restore \") || a.equals(\"--restore\")) r = true;\n        if (a.startsWith(\"--restore-with-checkpoint\")) rc = true;\n    }\n    return r && rc;\n}","tryCatchPattern":"try {\n    client.submit(args);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"mutually exclusive\")) {\n        log.error(\"Remove one of the conflicting flags: \" + e.getMessage());\n    }\n}","preventionTips":["Never template both --restore and --restore-with-checkpoint into scripts","Decide on one restore mechanism per job submission","Add shell-side flag conflict checks in wrapper scripts"],"tags":["cli","restore","validation"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}