{"id":"02f4f27f6787759d","repo":"junit-team/junit5","slug":"thread-mode-must-not-be-inferred","errorCode":null,"errorMessage":"thread mode must not be INFERRED","messagePattern":"thread mode must not be INFERRED","errorType":"exception","errorClass":"PreconditionViolationException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutInvocationFactory.java","lineNumber":43,"sourceCode":"/**\n * @since 5.9\n */\nclass TimeoutInvocationFactory {\n\n\tprivate final Store store;\n\n\tTimeoutInvocationFactory(Store store) {\n\t\tthis.store = Preconditions.notNull(store, \"store must not be null\");\n\t}\n\n\t<T extends @Nullable Object> Invocation<T> create(ThreadMode threadMode,\n\t\t\tTimeoutInvocationParameters<T> parameters) {\n\t\tPreconditions.notNull(parameters, \"timeout invocation parameters must not be null\");\n\t\treturn switch (Preconditions.notNull(threadMode, \"thread mode must not be null\")) {\n\t\t\tcase SAME_THREAD -> new SameThreadTimeoutInvocation<>(parameters,\n\t\t\t\tgetThreadExecutorForSameThreadInvocation());\n\t\t\tcase SEPARATE_THREAD -> new SeparateThreadTimeoutInvocation<>(parameters);\n\t\t\tcase INFERRED -> throw new PreconditionViolationException(\"thread mode must not be INFERRED\");\n\t\t};\n\t}\n\n\t@SuppressWarnings(\"resource\")\n\tprivate ScheduledExecutorService getThreadExecutorForSameThreadInvocation() {\n\t\treturn store.computeIfAbsent(SingleThreadExecutorResource.class).get();\n\t}\n\n\t@SuppressWarnings({ \"deprecation\", \"try\" })\n\tabstract static class ExecutorResource implements Store.CloseableResource, AutoCloseable {\n\n\t\tprivate final ScheduledExecutorService executor;\n\n\t\tExecutorResource(ScheduledExecutorService executor) {\n\t\t\tthis.executor = executor;\n\t\t}\n\n\t\tScheduledExecutorService get() {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TimeoutInvocationFactory.java#L25-L61","documentation":"Thrown by TimeoutInvocationFactory.create() when the ThreadMode passed in is INFERRED. INFERRED is a sentinel meaning 'resolve from the junit.jupiter.execution.timeout.thread.mode.default configuration parameter', and TimeoutExtension.resolveTimeoutThreadMode() resolves it to SAME_THREAD or SEPARATE_THREAD before the factory is called. This throw is an internal precondition assertion: if INFERRED reaches the factory, the resolution logic upstream failed.","triggerScenarios":"Calling TimeoutInvocationFactory.create(ThreadMode.INFERRED, parameters) directly. In normal JUnit operation, TimeoutExtension always resolves INFERRED before calling the factory, so this is only reachable by custom extensions that bypass TimeoutExtension's resolution step or by internal bugs.","commonSituations":"Not encountered in normal test usage. Could appear if a custom Extension directly instantiates TimeoutInvocationFactory and passes an unresolved ThreadMode.INFERRED.","solutions":["Resolve ThreadMode.INFERRED to SAME_THREAD or SEPARATE_THREAD before calling TimeoutInvocationFactory.create()","If using the standard @Timeout annotation, ensure no custom extension intercepts and replaces the resolved thread mode with INFERRED"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before calling TimeoutInvocationFactory.create(), resolve INFERRED:\nThreadMode resolved = (threadMode == ThreadMode.INFERRED)\n    ? ThreadMode.SAME_THREAD  // or read junit.jupiter.execution.timeout.thread.mode.default\n    : threadMode;\nassert resolved != ThreadMode.INFERRED;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always resolve ThreadMode.INFERRED to SAME_THREAD or SEPARATE_THREAD before passing it to TimeoutInvocationFactory","This error is internal; if using standard @Timeout annotations it should never surface"],"tags":["timeout","internal-assertion","thread-mode","junit-jupiter-engine"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}