private void checkNotEmptyDefinitions(WorkflowDef workflowDefinition) {
        Utils.checkNotNull(workflowDefinition, "WorkflowDefinition cannot be null");

        // Obtain the names of the tasks with missing definitions
        Set<String> missingTaskDefinitionNames =
                workflowDefinition.collectTasks().stream()
                        .filter(
                                workflowTask ->
                                        workflowTask.getType().equals(TaskType.SIMPLE.name()))
                        .filter(this::shouldPopulateTaskDefinition)
                        .map(WorkflowTask::getName)
                        .collect(Collectors.toSet());

        if (!missingTaskDefinitionNames.isEmpty()) {
            LOGGER.error(
                    "Cannot find the task definitions for the following tasks used in workflow: {}",
                    missingTaskDefinitionNames);
            Monitors.recordWorkflowStartError(
                    workflowDefinition.getName(), WorkflowContext.get().getClientApp());
            throw new IllegalArgumentException(
                    "Cannot find the task definitions for the following tasks used in workflow: "
                            + missingTaskDefinitionNames);
        }
    }
Populates metadata definitions within workflow objects. Benefits of loading and populating
metadata definitions upfront could be:

<ul>
  <li>Immutable definitions within a workflow execution with the added benefit of guaranteeing
      consistency at runtime.
  <li>Stress is reduced on the storage layer
</ul>
core/src/main/java/com/netflix/conductor/core/metadata/MetadataMapperService.java