{"record":{"id":"047f1f2d4d20239c","repo":"alibaba/spring-ai-alibaba","slug":"the-backoffmultiplier-must-be-1-0","errorCode":null,"errorMessage":"The backoffMultiplier must be >= 1.0","messagePattern":"The backoffMultiplier must be >= 1\\.0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/modelretry/ModelRetryInterceptor.java","lineNumber":336,"sourceCode":"\t\t/**\n\t\t * Set the maximum retry delay (milliseconds).\n\t\t * @param maxDelay Maximum delay time, in milliseconds\n\t\t */\n\t\tpublic Builder maxDelay(long maxDelay) {\n\t\t\tif (maxDelay < 0) {\n\t\t\t\tthrow new IllegalArgumentException(\"maxDelay must be greater than or equal to 0.\");\n\t\t\t}\n\t\t\tthis.maxDelay = maxDelay;\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n\t\t * Set the backoff factor (the multiplier for the delay time on each retry).\n\t\t * @param backoffMultiplier The retreat factor must be >= 1.0\n\t\t */\n\t\tpublic Builder backoffMultiplier(double backoffMultiplier) {\n\t\t\tif (backoffMultiplier < 1.0) {\n\t\t\t\tthrow new IllegalArgumentException(\"The backoffMultiplier must be >= 1.0\");\n\t\t\t}\n\t\t\tthis.backoffMultiplier = backoffMultiplier;\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n\t\t * Configure custom retryable exception handling logic\n\t\t * @param predicate Exception detection function\n\t\t */\n\t\tpublic Builder retryableExceptionPredicate(Predicate<Exception> predicate) {\n\t\t\tthis.retryableExceptionPredicate = predicate;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic ModelRetryInterceptor build() {\n\t\t\treturn new ModelRetryInterceptor(this);\n\t\t}\n","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/modelretry/ModelRetryInterceptor.java#L318-L354","documentation":"ModelRetryInterceptor.Builder.backoffMultiplier() requires a multiplier of at least 1.0 so exponential backoff never shrinks delay between retries. Values below 1.0 are rejected with IllegalArgumentException at build time.","triggerScenarios":"Calling backoffMultiplier() with a double < 1.0, e.g. backoffMultiplier(0.5) or backoffMultiplier(0).","commonSituations":"Confusing multiplier with a decay percentage; copying config from a library where 0.5 means something else; typos like 1.O vs 1.0.","solutions":["Pass a multiplier >= 1.0 (1.0 = fixed delay, 2.0 = doubling)","Use 1.0 if you want constant delay between retries","Fix the config value supplying the multiplier"],"exampleFix":"// before\nnew ModelRetryInterceptor.Builder().backoffMultiplier(0.5)\n// after\nnew ModelRetryInterceptor.Builder().backoffMultiplier(2.0)","handlingStrategy":"validation","validationCode":"if (multiplier < 1.0) { throw new IllegalArgumentException(\"backoffMultiplier must be >= 1.0\"); }\nbuilder.backoffMultiplier(multiplier);","typeGuard":"boolean isValidMultiplier(double m) { return m >= 1.0; }","tryCatchPattern":"try { builder.backoffMultiplier(v); } catch (IllegalArgumentException e) { log.warn(\"Bad backoffMultiplier, defaulting to 2.0\", e); builder.backoffMultiplier(2.0); }","preventionTips":["Remember 1.0 means constant delay; use >= 1.0 always","Sanitize config values that express percentages instead of multipliers","Add unit tests for builder edge values"],"tags":["config","retry","backoff","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}