{"record":{"id":"5515e64b13c5fe68","repo":"apache/seatunnel","slug":"the-jobid-must-not-be-empty-5515e6","errorCode":null,"errorMessage":"The jobId must not be empty.","messagePattern":"The jobId must not be empty\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/servlet/JobInfoServlet.java","lineNumber":48,"sourceCode":"public class JobInfoServlet extends BaseServlet {\n\n    private final JobInfoService jobInfoService;\n\n    public JobInfoServlet(NodeEngineImpl nodeEngine) {\n        super(nodeEngine);\n        this.jobInfoService = new JobInfoService(nodeEngine);\n    }\n\n    @Override\n    protected void doGet(HttpServletRequest req, HttpServletResponse resp)\n            throws ServletException, IOException {\n\n        String jobIdStr = req.getPathInfo();\n\n        if (jobIdStr != null && jobIdStr.length() > 1) {\n            jobIdStr = jobIdStr.substring(1);\n        } else {\n            throw new IllegalArgumentException(\"The jobId must not be empty.\");\n        }\n        Long jobId = Long.valueOf(jobIdStr);\n\n        writeJson(resp, jobInfoService.getJobInfoJson(jobId));\n    }\n}\n","sourceCodeStart":30,"sourceCodeEnd":55,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/servlet/JobInfoServlet.java#L30-L55","documentation":"JobInfoServlet.doGet strips the leading slash from pathInfo to get the jobId; when pathInfo is missing, empty, or only a slash, it throws IllegalArgumentException because job info lookup requires a specific job id. The servlet pattern is GET .../<jobId> returning the job's info JSON.","triggerScenarios":"GET the job-info endpoint without a /<jobId> path segment (pathInfo null, empty, or '/').","commonSituations":"Automation pipelines that lost the job id after submission failure; hand-typed URLs; load balancers normalizing trailing slashes away; client templates with an unfilled {jobId} placeholder.","solutions":["Include the numeric job id in the request path, e.g. GET /job-info/9218347100264553","Only invoke the endpoint after a successful job submission returned a jobId","Catch IllegalArgumentException and return a 400 with usage guidance","Log/propagate the jobId from job submission so it is never empty downstream"],"exampleFix":"// before\nfetch(`/job-info/${jobId}`); // jobId is undefined -> 'undefined'/empty\n// after\nif (!jobId) throw new Error('jobId required');\nfetch(`/job-info/${jobId}`);","handlingStrategy":"validation","validationCode":"if (jobId == null || jobId.isBlank() || !jobId.matches(\"\\\\d+\")) throw new IllegalArgumentException(\"valid numeric jobId required\");","typeGuard":"boolean isNumericJobId(String s) { return s != null && s.matches(\"\\\\d+\"); }","tryCatchPattern":"try { info = getJobInfo(jobId); } catch (IllegalArgumentException e) { redirectToListPage(); }","preventionTips":["Propagate the submitted job's id through your pipeline metadata store","Avoid hand-building job-info URLs from untrusted templates","Add client-side URL validation before fetch"],"tags":["rest","validation","jobid"],"backgroundTag":"empty-required-field","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}