{"record":{"id":"e3d2e8a11e6d878b","repo":"apache/pulsar","slug":"must-set-timeout-unit-for-timeout","errorCode":null,"errorMessage":"Must set timeout unit for timeout.","messagePattern":"Must set timeout unit for timeout\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client-api/src/main/java/org/apache/pulsar/client/api/BatchReceivePolicy.java","lineNumber":104,"sourceCode":"     * timeout for waiting for enough messages(enough number or enough bytes).\n     */\n    private final int timeout;\n    private final TimeUnit timeoutUnit;\n\n\n    /**\n     * If it is false, one time `batchReceive()` only can receive the single topic messages,\n     * the max messages and max size will not be strictly followed. (default: true).\n     */\n    private final boolean messagesFromMultiTopicsEnabled;\n\n    public void verify() {\n        if (maxNumMessages <= 0 && maxNumBytes <= 0 && timeout <= 0) {\n            throw new IllegalArgumentException(\"At least \"\n                    + \"one of maxNumMessages, maxNumBytes, timeout must be specified.\");\n        }\n        if (timeout > 0 && timeoutUnit == null) {\n            throw new IllegalArgumentException(\"Must set timeout unit for timeout.\");\n        }\n    }\n\n    public long getTimeoutMs() {\n        return (timeout > 0 && timeoutUnit != null) ? timeoutUnit.toMillis(timeout) : 0L;\n    }\n\n    public int getMaxNumMessages() {\n        return maxNumMessages;\n    }\n\n    public int getMaxNumBytes() {\n        return maxNumBytes;\n    }\n\n    public boolean isMessagesFromMultiTopicsEnabled() {\n        return messagesFromMultiTopicsEnabled;\n    }","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-api/src/main/java/org/apache/pulsar/client/api/BatchReceivePolicy.java#L86-L122","documentation":"BatchReceivePolicy.verify() additionally requires that if timeout is set (> 0), a timeoutUnit must also be provided; a timeout without a time unit is ambiguous and rejected with IllegalArgumentException. Internally getTimeoutMs() also silently yields 0 without a unit, so the check prevents a misleading no-timeout policy.","triggerScenarios":"Building a BatchReceivePolicy with timeout(N) (or a raw timeout field > 0) but never calling timeoutUnit/timeout(long, TimeUnit), then passing it to ConsumerBuilder.batchReceivePolicy().","commonSituations":"Using the builder's timeout(int) or setting fields directly on the policy without specifying the TimeUnit; deserializing policy from config where the unit field was omitted.","solutions":["Use the builder's timeout(long, TimeUnit) convenience so unit and value are set together.","If setting fields manually, also set timeoutUnit (e.g. TimeUnit.MILLISECONDS).","Set timeout <= 0 if you truly want no timeout, so the check is skipped."],"exampleFix":"// before\nBatchReceivePolicy policy = BatchReceivePolicy.builder()\n    .maxNumMessages(10)\n    .timeout(100)\n    .build();\n// after\nBatchReceivePolicy policy = BatchReceivePolicy.builder()\n    .maxNumMessages(10)\n    .timeout(100, TimeUnit.MILLISECONDS)\n    .build();","handlingStrategy":"validation","validationCode":"if (policy.getTimeout() > 0 && policy.getTimeoutUnit() == null) {\n    throw new IllegalArgumentException(\"timeout set without timeoutUnit\");\n}\npolicy.verify();","typeGuard":null,"tryCatchPattern":"try {\n    policy.verify();\n} catch (IllegalArgumentException e) {\n    log.error(\"BatchReceivePolicy misconfigured: {}\", e.getMessage());\n}","preventionTips":["Always use the builder's timeout(long, TimeUnit) overload so the unit is never omitted.","Never set the timeout field directly without also setting timeoutUnit."],"tags":["pulsar","consumer","configuration","time-unit"],"backgroundTag":"invalid-policy-configuration","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}