Repository: PrefectHQ/prefect

Issue:
ValueError: Multiple flows cannot be used with the same case statement
## Description
Hi - `apply_map` in a `case` branch return a  `ValueError: Multiple flows cannot be used with the same case statement`.  
```
Traceback (most recent call last):
  File "/tst2.py", line 66, in <module>
    result = apply_map(inc_or_negate, range(4))
  File "/miniconda3/lib/python3.7/site-packages/prefect/utilities/tasks.py", line 127, in apply_map
    flow.add_task(task)
  File "/miniconda3/lib/python3.7/site-packages/prefect/core/flow.py", line 529, in add_task
    case.add_task(task, self)
  File "/miniconda3/lib/python3.7/site-packages/prefect/tasks/control_flow/case.py", line 77, in add_task
    "Multiple flows cannot be used with the same case statement"
ValueError: Multiple flows cannot be used with the same case statement
```
Interestingly `apply_map` works in certain situations in an `ifelse` branch.
![image](https://user-images.githubusercontent.com/16763201/92680637-fbdf2700-f2f0-11ea-963c-2980ae23bc19.png)

### `apply_map`  in an `ifelse` branch`
```
@task
def inc(x):
    return x + 1

@task
def negate(x):
    return -x

@task
def is_even(x):
    return x % 2 == 0

def inc_or_negate(x):
    cond = is_even(x)
    # If x is even, increment it
    with case(cond, True):
        res1 = inc(x)
    # If x is odd, negate it
    with case(cond, False):
        res2 = negate(x)
    return merge(res1, res2)

@task
def is_int_or_string(int_or_string):
  return isinstance(int_or_string, int)

@task
def hello(some_str):
  print("Hello ", some_str)

@task
def list_maker(input_num):
  print(input_num)
  lst = [random.randint(1, 10) for i in range(input_num)]
  print(lst)
  return lst


with Flow("apply-map example") as flow:
  int_or_string = Parameter("int_or_string")
  
  instance_type_int = is_int_or_string(int_or_string)

  num_lst = list_maker(int_or_string)

  str_result = hello(int_or_string)

  ifelse(
    instance_type_int,
    num_lst,
    str_result
  )

  int_result = apply_map(inc_or_negate, num_lst)
    

def tri_recursion(k):
  if(k > 0):
    result = k + tri_recursion(k - 1)
    print(result)
  else:
    result = 0
  return result

if __name__ == "__main__":
    flow.visualize()
    state = flow.run(
      parameters=dict(int_or_string=2)
    )
    flow.visualize(flow_state=state)
```
### `apply_map`  in a `case` branch`
The example below is essentially the [Complex mapped pipelines](https://docs.prefect.io/core/concepts/mapping.html#complex-mapped-pipelines) with an extra case statement before the `apply_map`.  


## Reproduction
from prefect import Flow, task, case, apply_map
from prefect.tasks.control_flow import merge

```
@task
def inc(x):
    return x + 1

@task
def negate(x):
    return -x

@task
def is_even(x):
    return x % 2 == 0

def inc_or_negate(x):
    cond = is_even(x)
    # If x is even, increment it
    with case(cond, True):
        res1 = inc(x)
    # If x is odd, negate it
    with case(cond, False):
        res2 = negate(x)
    return merge(res1, res2)

@task
def is_int_or_string(int_or_string):
  if isinstance(int_or_string, int):
    cond = "int"
  return cond

@task
def hello(some_str):
  print("Hello ", some_str)

with Flow("apply-map example") as flow:
  int_or_string = Parameter("int_or_string")
  
  instance_type = is_int_or_string(int_or_string)

  with case(instance_type, "int"):
    result = apply_map(inc_or_negate, range(4))
```





## Environment
`prefect` 13.5+

Optionally run `prefect diagnostics` from the command line and paste the information here. -->



Discussion:
@cicdw I think this is a similar issue I ran into with `flow.update` except with conditionals
Ah, this is a fun edge case - `apply_map` is implemented by creating a temporary subflow before merging that flow back into the main flow. The contextual `case` statement needs to be cleared while creating this subflow, otherwise the case statement detects multiple flows and errors like above.

Simple one line fix (plus tests), I've gotten things working locally already for your example. Will push a PR up later today, thanks for the issue report.

```
$ python test.py
[2020-09-10 17:48:27] INFO - prefect.FlowRunner | Beginning Flow run for 'apply-map example'
[2020-09-10 17:48:27] DEBUG - prefect.FlowRunner | Flow 'apply-map example': Handling state change from Scheduled to Running
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'int_or_string': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'int_or_string': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'int_or_string': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'int_or_string': Handling state change from Running to Success
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'int_or_string': finished task run for task with final state: 'Success'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_int_or_string': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_int_or_string': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_int_or_string': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_int_or_string': Handling state change from Running to Success
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_int_or_string': finished task run for task with final state: 'Success'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(int)': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(int)': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(int)': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(int)': Handling state change from Running to Success
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(int)': finished task run for task with final state: 'Success'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even': Handling state change from Pending to Mapped
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even': finished task run for task with final state: 'Mapped'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even[0]': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[0]': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[0]': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[0]': Handling state change from Running to Success
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even[0]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even[1]': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[1]': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[1]': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[1]': Handling state change from Running to Success
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even[1]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even[2]': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[2]': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[2]': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[2]': Handling state change from Running to Success
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even[2]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even[3]': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[3]': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[3]': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'is_even[3]': Handling state change from Running to Success
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'is_even[3]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(False)': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)': Handling state change from Pending to Mapped
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(False)': finished task run for task with final state: 'Mapped'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(False)[0]': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[0]': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[0]': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | SKIP signal raised: SKIP('Provided value "True" did not match "False"')
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[0]': Handling state change from Running to Skipped
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(False)[0]': finished task run for task with final state: 'Skipped'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(False)[1]': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[1]': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[1]': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[1]': Handling state change from Running to Success
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(False)[1]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(False)[2]': Starting task run...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[2]': Handling state change from Pending to Running
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[2]': Calling task.run() method...
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | SKIP signal raised: SKIP('Provided value "True" did not match "False"')
[2020-09-10 17:48:27] DEBUG - prefect.TaskRunner | Task 'case(False)[2]': Handling state change from Running to Skipped
[2020-09-10 17:48:27] INFO - prefect.TaskRunner | Task 'case(False)[2]': finished task run for task with final state: 'Skipped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(False)[3]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(False)[3]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(False)[3]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(False)[3]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(False)[3]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)': Handling state change from Pending to Mapped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)': finished task run for task with final state: 'Mapped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)[0]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[0]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[0]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[0]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)[0]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)[1]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[1]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[1]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | SKIP signal raised: SKIP('Provided value "False" did not match "True"')
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[1]': Handling state change from Running to Skipped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)[1]': finished task run for task with final state: 'Skipped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)[2]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[2]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[2]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[2]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)[2]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)[3]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[3]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[3]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | SKIP signal raised: SKIP('Provided value "False" did not match "True"')
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'case(True)[3]': Handling state change from Running to Skipped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'case(True)[3]': finished task run for task with final state: 'Skipped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate': Handling state change from Pending to Mapped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate': finished task run for task with final state: 'Mapped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate[0]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[0]': Upstream states were skipped; ending run.
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[0]': Handling state change from Pending to Skipped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate[0]': finished task run for task with final state: 'Skipped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate[1]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[1]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[1]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[1]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate[1]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate[2]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[2]': Upstream states were skipped; ending run.
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[2]': Handling state change from Pending to Skipped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate[2]': finished task run for task with final state: 'Skipped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate[3]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[3]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[3]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'negate[3]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'negate[3]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc': Handling state change from Pending to Mapped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc': finished task run for task with final state: 'Mapped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc[0]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[0]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[0]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[0]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc[0]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc[1]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[1]': Upstream states were skipped; ending run.
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[1]': Handling state change from Pending to Skipped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc[1]': finished task run for task with final state: 'Skipped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc[2]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[2]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[2]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[2]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc[2]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc[3]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[3]': Upstream states were skipped; ending run.
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'inc[3]': Handling state change from Pending to Skipped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'inc[3]': finished task run for task with final state: 'Skipped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge': Handling state change from Pending to Mapped
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge': finished task run for task with final state: 'Mapped'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge[0]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[0]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[0]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[0]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge[0]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge[1]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[1]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[1]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[1]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge[1]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge[2]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[2]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[2]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[2]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge[2]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge[3]': Starting task run...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[3]': Handling state change from Pending to Running
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[3]': Calling task.run() method...
[2020-09-10 17:48:28] DEBUG - prefect.TaskRunner | Task 'Merge[3]': Handling state change from Running to Success
[2020-09-10 17:48:28] INFO - prefect.TaskRunner | Task 'Merge[3]': finished task run for task with final state: 'Success'
[2020-09-10 17:48:28] INFO - prefect.FlowRunner | Flow run SUCCESS: all reference tasks succeeded
[2020-09-10 17:48:28] DEBUG - prefect.FlowRunner | Flow 'apply-map example': Handling state change from Running to Success
```
Hmmmm, so the fix here is quick and simple, but it shows a larger problem in prefect's task-runner pipeline - mapped tasks don't play with task skipping if `skip_on_upstream_skip=False`. For most tasks, if any upstream task is skipped, then you also want to skip that task. This works fine for mapped and unmapped tasks equally. However, if mapped tasks have `skip_on_upstream_skip=False` (as is done for `merge` tasks) and any upstream task is skipped, an error shows up in the processing pipeline, as the following check fails:

https://github.com/PrefectHQ/prefect/blob/e5e1c741d88cd4cca3b1196cbee89b5249f8a2cf/src/prefect/engine/task_runner.py#L437-L445

I'm going to push up the PR to unblock using `apply_map` inside a `case` block, but note that skipping mapped `merge` tasks won't work until this other issue is fixed.

Resolving patch:
diff --git a/src/prefect/core/flow.py b/src/prefect/core/flow.py
--- a/src/prefect/core/flow.py
+++ b/src/prefect/core/flow.py
@@ -521,9 +521,9 @@ def add_task(self, task: Task) -> Task:
             self.tasks.add(task)
             self._cache.clear()
 
-            # Parameters must be root tasks
+            # Parameters and constants must be root tasks
             # All other new tasks should be added to the current case/resource (if any)
-            if not isinstance(task, Parameter):
+            if not isinstance(task, (Parameter, prefect.tasks.core.constants.Constant)):
                 case = prefect.context.get("case", None)
                 if case is not None:
                     case.add_task(task, self)
diff --git a/src/prefect/utilities/tasks.py b/src/prefect/utilities/tasks.py
--- a/src/prefect/utilities/tasks.py
+++ b/src/prefect/utilities/tasks.py
@@ -115,7 +115,9 @@ def preprocess(a: Any) -> "prefect.Task":
     kwargs2 = {k: preprocess(v) for k, v in kwargs.items()}
 
     # Construct a temporary flow for the subgraph
-    with prefect.context(mapped=True):
+    # We set case=None & resource=None to ignore any external case/resource
+    # blocks while constructing the temporary flow.
+    with prefect.context(mapped=True, case=None, resource=None):
         with flow2:
             if no_flow_provided:
                 res = func(*args2, **kwargs2)


Test patch:
diff --git a/tests/tasks/test_control_flow.py b/tests/tasks/test_control_flow.py
--- a/tests/tasks/test_control_flow.py
+++ b/tests/tasks/test_control_flow.py
@@ -6,7 +6,6 @@
 from prefect.engine.state import Skipped, Success
 from prefect.tasks.control_flow import FilterTask, ifelse, merge, switch, case
 from prefect.tasks.control_flow.conditional import CompareValue
-from prefect.tasks.core.constants import Constant
 
 
 class Condition(Task):
@@ -158,7 +157,7 @@ def test_merge_imperative_flow():
     c = merge(a, b, flow=flow)
 
     state = flow.run()
-    assert state.result[cond].result == True
+    assert state.result[cond].result is True
     assert state.result[a].result == 2
     assert state.result[b].is_skipped()
     assert state.result[c].result == 2
@@ -591,3 +590,15 @@ def test_case_with_parameters(self):
         state = flow.run(x=1)
         assert state.result[y1].result == 2
         assert state.result[y2].is_skipped()
+
+    def test_case_with_constants(self):
+        with Flow("test") as flow:
+            cond = identity(True)
+            with case(cond, True):
+                res = inc.map(range(4))
+            with case(cond, False):
+                res2 = inc.map(range(4))
+
+        state = flow.run()
+        assert state.result[res].result == [1, 2, 3, 4]
+        assert state.result[res2].is_skipped()
diff --git a/tests/utilities/test_tasks.py b/tests/utilities/test_tasks.py
--- a/tests/utilities/test_tasks.py
+++ b/tests/utilities/test_tasks.py
@@ -1,6 +1,6 @@
 import pytest
 
-from prefect import Flow, Task, case
+from prefect import Flow, Task, case, Parameter
 from prefect.engine.flow_runner import FlowRunner
 from prefect.engine.state import Paused, Resume
 from prefect.utilities import tasks, edges
@@ -301,6 +301,26 @@ def edge_info(task):
         }
         assert res == sol
 
+    def test_apply_map_inside_case_statement_works(self):
+        def func(x):
+            return add(x, 1), add(x, 2)
+
+        with Flow("test") as flow:
+            branch = Parameter("branch")
+            with case(branch, True):
+                a, b = apply_map(func, range(4))
+                c = add.map(a, b)
+
+        state = flow.run(branch=True)
+        assert state.result[a].result == [1, 2, 3, 4]
+        assert state.result[b].result == [2, 3, 4, 5]
+        assert state.result[c].result == [3, 5, 7, 9]
+
+        state = flow.run(branch=False)
+        assert state.result[a].is_skipped()
+        assert state.result[b].is_skipped()
+        assert state.result[c].is_skipped()
+
 
 class TestAsTask:
     @pytest.mark.parametrize(