flowable/flowable-engine · error · FlowableException

Error reading json value ${configuration}

Error message

Error reading json value ${configuration}

What it means

TimerSuspendProcessDefinitionHandler parses its job handler configuration string as JSON to read the 'includeProcessInstances' flag; if readTree or the flag extraction throws, the handler wraps the failure in FlowableException('Error reading json value ' + configuration). The raw configuration text is embedded in the message to aid diagnosis.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/jobexecutor/TimerSuspendProcessDefinitionHandler.java:45

public class TimerSuspendProcessDefinitionHandler extends TimerChangeProcessDefinitionSuspensionStateJobHandler {

    public static final String TYPE = "suspend-processdefinition";

    @Override
    public String getType() {
        return TYPE;
    }

    @Override
    public void execute(Job job, String configuration, ExecutionEntity execution, CommandContext commandContext) {
        ProcessEngineConfigurationImpl processEngineConfiguration = commandContext.getProcessEngineConfiguration();

        boolean suspendProcessInstances = false;
        try {
            JsonNode configNode = processEngineConfiguration.getObjectMapper().readTree(configuration);
            suspendProcessInstances = getIncludeProcessInstances(configNode);
        } catch (Exception e) {
            throw new FlowableException("Error reading json value " + configuration, e);
        }

        String processDefinitionId = job.getProcessDefinitionId();

        SuspendProcessDefinitionCmd suspendProcessDefinitionCmd = new SuspendProcessDefinitionCmd(processDefinitionId, null, suspendProcessInstances, null, job.getTenantId());
        suspendProcessDefinitionCmd.execute(commandContext);
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect the job's configuration (ACT_RU_JOB.JOB_HANDLER_CFG_) and fix it to the JSON shape the current version expects: {"includeProcessInstances":true|false,"processDefinitionId":"..."} or delete the stale job
  2. Align engine versions: run the upgrade job-cfg migration scripts or ensure all cluster nodes run the same Flowable version
  3. Suspend the definition manually to achieve the intended effect: repositoryService.suspendProcessDefinitionById(id, true, null), then remove the broken job
  4. Recreate the scenario if needed via a fresh ProcessDefinitionSuspension schedule so the engine writes a well-formed configuration

Example fix

// before: corrupted job config, job keeps failing
// after: suspend manually and remove the failing job
repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
Job job = managementService.createJobQuery().jobId(jobId).singleResult();
managementService.deleteJob(job.getId());
Defensive patterns

Strategy: validation

Validate before calling

ObjectNode cfg = objectMapper.createObjectNode();
cfg.put("includeProcessInstances", true);
// store cfg.toString() as the job handler configuration; verify before firing:
JsonNode n = objectMapper.readTree(job.getJobHandlerConfiguration());
if (!n.has("includeProcessInstances")) throw new IllegalStateException("malformed suspension job config: " + job.getJobHandlerConfiguration());

Type guard

boolean isValidSuspensionConfig(String cfg) {
  try {
    JsonNode n = objectMapper.readTree(cfg);
    return n != null && n.has("includeProcessInstances") && n.get("includeProcessInstances").isBoolean();
  } catch (Exception e) { return false; }
}

Try / catch

try {
  managementService.executeJob(suspendJobId);
} catch (FlowableException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Error reading json value")) {
    log.error("corrupt suspension job cfg: {}", e.getMessage());
    managementService.deleteJob(suspendJobId); // or repair cfg then re-execute
  } else { throw e; }
}

Prevention

When it happens

Trigger: A suspend-process-definition timer job whose JOB_HANDLER_CFG_ column is not valid JSON, or valid JSON lacking the expected includeProcessInstances field that getIncludeProcessInstances requires.

Common situations: Jobs written by an older engine version read by a newer one after upgrade (config schema changed); manual edits or data migrations that corrupted the configuration column; copying jobs across environments with mismatched engine versions.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/4aa2e2ec9e51d018. Report an issue: GitHub.