{"record":{"id":"84431d88cbdcedaf","repo":"Tencent/matrix","slug":"can-t-be-here-without-a-job-id","errorCode":null,"errorMessage":"Can't be here without a job id","messagePattern":"Can't be here without a job id","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-android/src/main/java/com/tencent/matrix/resource/MatrixJobIntentService.java","lineNumber":548,"sourceCode":"    public static void enqueueWork(@NonNull Context context, @NonNull ComponentName component,\n                                   int jobId, @NonNull Intent work) {\n        if (work == null) {\n            throw new IllegalArgumentException(\"work must not be null\");\n        }\n        synchronized (sLock) {\n            WorkEnqueuer we = getWorkEnqueuer(context, component, true, jobId);\n            we.ensureJobId(jobId);\n            we.enqueueWork(work);\n        }\n    }\n\n    static WorkEnqueuer getWorkEnqueuer(Context context, ComponentName cn, boolean hasJobId,\n                                        int jobId) {\n        WorkEnqueuer we = sClassWorkEnqueuer.get(cn);\n        if (we == null) {\n            if (Build.VERSION.SDK_INT >= 26) {\n                if (!hasJobId) {\n                    throw new IllegalArgumentException(\"Can't be here without a job id\");\n                }\n                we = new JobWorkEnqueuer(context, cn, jobId);\n            } else {\n                we = new CompatWorkEnqueuer(context, cn);\n            }\n            sClassWorkEnqueuer.put(cn, we);\n        }\n        return we;\n    }\n\n    /**\n     * Called serially for each work dispatched to and processed by the service.  This\n     * method is called on a background thread, so you can do long blocking operations\n     * here.  Upon returning, that work will be considered complete and either the next\n     * pending work dispatched here or the overall service destroyed now that it has\n     * nothing else to do.\n     *\n     * <p>Be aware that when running as a job, you are limited by the maximum job execution","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-android/src/main/java/com/tencent/matrix/resource/MatrixJobIntentService.java#L530-L566","documentation":"MatrixJobIntentService.getWorkEnqueuer() picks the right WorkEnqueuer implementation for a component. On Android API 26+ work must be submitted through JobScheduler, which requires a job id; if the caller reaches this path without one (hasJobId == false), the library throws IllegalArgumentException because a JobWorkEnqueuer cannot be created without a jobId.","triggerScenarios":"On devices running Android 8.0 (API 26) or newer, a code path resolves a WorkEnqueuer for a component with hasJobId=false — i.e. enqueueWork (or an internal caller) was invoked without a valid jobId >= 0.","commonSituations":"Calling an enqueue/start overload that omits jobId on an API 26+ device; passing jobId <= 0 or an invalid sentinel so the id is treated as absent; device-dependent behavior where the bug only reproduces on Oreo+.","solutions":["Always pass a valid positive jobId (used as the JobScheduler job id) when calling enqueueWork on API 26+ devices.","Verify the call chain does not route through a variant that strips the jobId parameter before reaching getWorkEnqueuer.","Test on an API 26+ emulator/device, since CompatWorkEnqueuer is used below API 26 and masks the bug."],"exampleFix":"// before\nMatrixJobIntentService.enqueueWork(context, component, 0, work); // treated as no job id\n// after\nMatrixJobIntentService.enqueueWork(context, component, JOB_ID_LEAK_SERVICE /* >= 1 */, work);","handlingStrategy":"validation","validationCode":"if (Build.VERSION.SDK_INT >= 26 && jobId <= 0) {\n    throw new IllegalStateException(\"jobId required on API 26+\");\n}\nMatrixJobIntentService.enqueueWork(context, component, jobId, work);","typeGuard":null,"tryCatchPattern":"try {\n    MatrixJobIntentService.enqueueWork(context, component, jobId, work);\n} catch (IllegalArgumentException e) {\n    Log.e(TAG, \"missing/invalid jobId for API 26+ enqueue\", e);\n}","preventionTips":["Define jobId as a named positive constant per service, never 0 or computed dynamically.","Test enqueue paths on an API 26+ emulator where JobScheduler is mandatory.","Avoid calling legacy startService-style overloads that omit jobId on Oreo+."],"tags":["android","jobscheduler","api-level","illegal-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}