{"record":{"id":"f7ba38be8af13d6a","repo":"flowable/flowable-engine","slug":"failedjobretrytimecycle-has-wrong-format-faile","errorCode":null,"errorMessage":"failedJobRetryTimeCycle has wrong format:\" + failedJobRetryTimeCycleValue + \" for execution \" + executionEntity","messagePattern":"failedJobRetryTimeCycle has wrong format:\" \\+ failedJobRetryTimeCycleValue \\+ \" for execution \" \\+ executionEntity","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/JobRetryCmd.java","lineNumber":144,"sourceCode":"                if (jobRetries <= 1 || isUnrecoverableException()) {\n                    newJobEntity = jobService.moveJobToDeadLetterJob(job);\n                } else {\n                    newJobEntity = timerJobService.moveJobToTimerJob(job);\n                }\n\n                newJobEntity.setDuedate(durationHelper.getDateAfter());\n\n                if (job.getExceptionMessage() == null) { // is it the first exception\n                    LOGGER.debug(\"Applying JobRetryStrategy '{}' the first time for job {} with {} retries\", failedJobRetryTimeCycleValue, job.getId(), durationHelper.getTimes());\n\n                } else {\n                    LOGGER.debug(\"Decrementing retries of JobRetryStrategy '{}' for job {}\", failedJobRetryTimeCycleValue, job.getId());\n                }\n\n                newJobEntity.setRetries(jobRetries - 1);\n\n            } catch (Exception e) {\n                throw new FlowableException(\"failedJobRetryTimeCycle has wrong format:\" + failedJobRetryTimeCycleValue + \" for execution \" + executionEntity, e);\n            }\n        }\n\n        if (exception != null) {\n            newJobEntity.setExceptionMessage(exception.getMessage());\n            newJobEntity.setExceptionStacktrace(getExceptionStacktrace());\n        }\n\n        // Dispatch both an update and a retry-decrement event\n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n        FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();\n        if (eventDispatcher != null && eventDispatcher.isEnabled()) {\n            eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_UPDATED, newJobEntity),\n                    processEngineConfiguration.getEngineCfgKey());\n            eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.JOB_RETRIES_DECREMENTED, newJobEntity),\n                    processEngineConfiguration.getEngineCfgKey());\n        }\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/JobRetryCmd.java#L126-L162","documentation":"JobRetryCmd parses the failedJobRetryTimeCycle value (e.g. 'R5/PT1M') to compute job retry decrements. If parsing/applying the retry cycle throws any Exception, it is wrapped as FlowableException 'failedJobRetryTimeCycle has wrong format:<value> for execution <execution>', with the original parse failure as cause.","triggerScenarios":"An async job failed and the execution/element has a failedJobRetryTimeCycle configured (in BPMN extension elements or process engine configuration) whose value is not a valid ISO-8601 repetition interval, e.g. '5', 'R/PT10M', 'PTx', or containing typos.","commonSituations":"Typo in the time cycle string in the BPMN XML; property placeholder not resolved so a raw '${retryCycle}' ends up in the value; copying examples with wrong interval syntax; configuration injected from environment variables with bad values.","solutions":["Fix the failedJobRetryTimeCycle value to valid ISO-8601 repetition format, e.g. 'R3/PT10M' (3 retries every 10 minutes).","Check the exception cause in the logs to see exactly which parser rejected the value.","If the value comes from a placeholder/property, confirm it resolves to a literal value before deployment.","Remove the cycle temporarily to let the job fail normally while you correct configuration."],"exampleFix":"// before\n<flowable:failedJobRetryTimeCycle>${retryCycle}</flowable:failedJobRetryTimeCycle>\n// after\n<flowable:failedJobRetryTimeCycle>R5/PT7M</flowable:failedJobRetryTimeCycle>","handlingStrategy":"validation","validationCode":"private static final Pattern RETRY_CYCLE =\n    Pattern.compile(\"^R\\\\d+/PT?\\\\d+[HMS]$\");\nif (!RETRY_CYCLE.matcher(failedJobRetryTimeCycle).matches()) {\n    throw new IllegalArgumentException(\"Invalid retry time cycle: \" + failedJobRetryTimeCycle);\n}","typeGuard":"boolean isValidRetryTimeCycle(String v) {\n    return v != null && v.matches(\"^R\\\\d+/PT?\\\\d+[HMS]$\");\n}","tryCatchPattern":"try {\n    managementService.moveJobToDeadLetterJob(jobId);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"failedJobRetryTimeCycle has wrong format\")) {\n        log.error(\"Fix failedJobRetryTimeCycle value; cause: {}\", e.getCause(), e);\n    }\n    throw e;\n}","preventionTips":["Use ISO-8601 repetition format like R5/PT10M for failedJobRetryTimeCycle","Verify placeholders in BPMN XML resolve to literals before deployment","Validate the cycle string in a unit test parsing it with the same engine parser"],"tags":["flowable","async-job","retry-configuration","format-error"],"backgroundTag":"invalid-argument-format","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}