{"record":{"id":"eeb01e9427bebe50","repo":"windmill-labs/windmill","slug":"module-exponential-backoff-base-seconds-mu","errorCode":null,"errorMessage":"Module '{}': Exponential backoff base (seconds) must be greater than 0. A base of 0 would cause immediate retries.","messagePattern":"Module '(.+?)': Exponential backoff base \\(seconds\\) must be greater than 0\\. A base of 0 would cause immediate retries\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-types/src/flows.rs","lineNumber":212,"sourceCode":"            schema: self.schema,\n            tag: self.tag,\n            dedicated_worker: self.dedicated_worker,\n            timeout: self.timeout,\n            deployment_message: self.deployment_message,\n            visible_to_runner_only: self.visible_to_runner_only,\n            on_behalf_of_email: self.on_behalf_of_email,\n            on_behalf_of: self.on_behalf_of,\n            preserve_on_behalf_of: self.preserve_on_behalf_of,\n            ws_error_handler_muted: self.ws_error_handler_muted,\n            labels: self.labels,\n            skip_draft_deletion: self.skip_draft_deletion,\n        }\n    }\n}\n\nfn validate_retry(retry: &Retry, module_id: &str) -> anyhow::Result<()> {\n    if retry.exponential.attempts > 0 && retry.exponential.seconds == 0 {\n        return Err(anyhow::anyhow!(\n            \"Module '{}': Exponential backoff base (seconds) must be greater than 0. A base of 0 would cause immediate retries.\",\n            module_id\n        ));\n    }\n    Ok(())\n}\n\n/// Script/sub-flow step references must be workspace paths (`u/`, `f/`, `g/`) or a hub\n/// reference (`hub/`). Empty is tolerated for intermediate/incomplete steps. This blocks\n/// absolute or local filesystem paths (e.g. `/tmp/.../ops/scripts/...` baked in by a\n/// `wmill sync push` from a feature-branch checkout) from being persisted into a flow,\n/// where they silently mis-resolve to an unrelated script at runtime (#9751).\nfn is_workspace_runnable_path(path: &str) -> bool {\n    path.is_empty()\n        || path.starts_with(\"u/\")\n        || path.starts_with(\"f/\")\n        || path.starts_with(\"g/\")\n        || path.starts_with(\"hub/\")","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-types/src/flows.rs#L194-L230","documentation":"Flow validation checks each module's retry policy. An exponential backoff policy with attempts > 0 but a base of 0 seconds is invalid because the base is the initial delay multiplier — with 0 every retry fires immediately with no backoff, so validation rejects the flow.","triggerScenarios":"Saving or validating a flow (validate_flow_value, called on flow create/update) where any module has retry.exponential.attempts set to a positive number while retry.exponential.seconds is 0.","commonSituations":"Building flows via API/CLI where the retry object is partially filled (attempts set, seconds left at default 0), UI form bugs, or copying retry configs between fixed-interval and exponential retry types.","solutions":["Set retry.exponential.seconds to a positive value (e.g. 1) whenever attempts > 0","If retries aren't wanted, set exponential.attempts to 0 instead of leaving seconds at 0","Validate the flow JSON locally before deploying"],"exampleFix":"// before\n\"retry\": {\"exponential\": {\"attempts\": 3, \"seconds\": 0}}\n// after\n\"retry\": {\"exponential\": {\"attempts\": 3, \"seconds\": 1}}","handlingStrategy":"validation","validationCode":"function validateRetry(retry) {\n  if (retry?.exponential?.attempts > 0 && retry.exponential.seconds <= 0)\n    throw new Error(\"exponential backoff base (seconds) must be > 0 when attempts > 0\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When setting exponential attempts, always set seconds (e.g. 1) together","Use the flow editor's retry form rather than raw JSON where possible","Add a shared retry-config builder that defaults seconds > 0"],"tags":["validation","flows","retry","configuration"],"backgroundTag":"invalid-retry-config","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}