{"record":{"id":"a08d9a33740b45a2","repo":"apache/seatunnel","slug":"please-provide-jobid-when-start-with-save-point","errorCode":null,"errorMessage":"Please provide jobId when start with save point.","messagePattern":"Please provide jobId when start with save point\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/JobInfoService.java","lineNumber":394,"sourceCode":"                job -> {\n                    handleStopJob(job, getSeaTunnelServer(false), nodeEngine.getNode());\n                    jsonResponse.add(\n                            new JsonObject()\n                                    .add(RestConstant.JOB_ID, (Long) job.get(RestConstant.JOB_ID)));\n                });\n\n        return jsonResponse;\n    }\n\n    public JsonObject submitJob(Map<String, String> requestParams, byte[] requestBody) {\n\n        if (requestParams.containsKey(RestConstant.DRY_RUN)\n                && requestParams.get(RestConstant.DRY_RUN) != null) {\n            throw new IllegalArgumentException(\"Dry-run is only supported via CLI\");\n        }\n        if (Boolean.parseBoolean(requestParams.get(RestConstant.IS_START_WITH_SAVE_POINT))\n                && requestParams.get(RestConstant.JOB_ID) == null) {\n            throw new IllegalArgumentException(\"Please provide jobId when start with save point.\");\n        }\n        validateCheckpointRestoreRequest(requestParams);\n        Config config;\n        ConfigFormat configFormat = ConfigFormat.fromString(requestParams.get(CONFIG_FORMAT));\n\n        switch (configFormat) {\n            case HOCON:\n                config = ConfigFactory.parseString(new String(requestBody, StandardCharsets.UTF_8));\n                break;\n            case SQL:\n                config = SqlConfigBuilder.of(new String(requestBody, StandardCharsets.UTF_8));\n                break;\n            case JSON:\n            default:\n                config = RestUtil.buildConfig(requestHandle(requestBody));\n                break;\n        }\n","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/service/JobInfoService.java#L376-L412","documentation":"SeaTunnel's REST job submission supports resuming a job from an existing save point, but a save point is keyed by the original jobId. The REST endpoint refuses to start with a save point when the jobId parameter is missing, because it cannot know which saved state to restore. It is thrown as an IllegalArgumentException during request validation in submitJob before any job is created.","triggerScenarios":"POST to the REST job submission endpoint with isStartWithSavePoint=true (or a truthy value) in the request params while omitting the jobId parameter; e.g. curl -X POST .../submit-job -d 'isStartWithSavePoint=true' without '&jobId=<id>'.","commonSituations":"Developers migrating from CLI-based -s/--savepoint workflows to the HTTP API forget that REST requires the explicit jobId; scripting tools that build the query string dynamically drop empty jobId params; retrying a savepoint restore after the original jobId was lost.","solutions":["Add the jobId of the original job to the request parameters (jobId=<originalJobId>) alongside isStartWithSavePoint=true.","If you do not know the original jobId, list jobs via the REST job-info endpoint or 'seatunnel.sh -l' to find it before restoring.","If you intended a fresh start, remove the isStartWithSavePoint parameter entirely instead of setting it with no jobId."],"exampleFix":"// before\ncurl -X POST 'http://host:8080/submit-job?jobName=demo&isStartWithSavePoint=true' --data @job.conf\n// after\ncurl -X POST 'http://host:8080/submit-job?jobName=demo&isStartWithSavePoint=true&jobId=861119875632570369' --data @job.conf","handlingStrategy":"validation","validationCode":"if (params.getOrDefault(\"isStartWithSavePoint\", \"false\") == \"true\" && !params.containsKey(\"jobId\")) {\n  throw new Error(\"REST savepoint start requires jobId\");\n}","typeGuard":null,"tryCatchPattern":"try { submit(url, params); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"jobId when start with save point\")) { /* prompt user for original jobId */ } else throw e; }","preventionTips":["Always store the jobId returned by the first submission for later savepoint restores.","Build REST query strings from an explicit parameter whitelist so savepoint flags always accompany jobId.","Never hardcode savepoint restore calls without recording the source job's id."],"tags":["rest-api","savepoint","missing-parameter","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}