public static FlowGraph of(GraphCluster graph) throws IllegalVariableEvaluationException {
        return FlowGraph.builder()
            .nodes(GraphUtils.nodes(graph))
            .edges(GraphUtils.edges(graph))
            .clusters(GraphUtils.clusters(graph, new ArrayList<>())
                .stream()
                .map(g -> new Cluster(g.getKey(), g.getKey().getGraph()
                    .nodes()
                    .stream()
                    .map(AbstractGraph::getUid)
                    .toList(),
                    g.getValue(),
                    g.getKey().getRoot().getUid(),
                    g.getKey().getEnd().getUid()
                ))
                .toList()
            )
            .build();
    }
@Test
    void dynamicIdSubflow() throws IllegalVariableEvaluationException, TimeoutException {
        Flow flow = this.parse("flows/valids/task-flow-dynamic.yaml").toBuilder().revision(1).build();

        IllegalArgumentException illegalArgumentException = Assertions.assertThrows(IllegalArgumentException.class, () -> graphService.flowGraph(flow, Collections.singletonList("root.launch")));
        assertThat(illegalArgumentException.getMessage(), is("Can't expand subflow task 'launch' because namespace and/or flowId contains dynamic values. This can only be viewed on an execution."));

        Execution execution = runnerUtils.runOne(null, "io.kestra.tests", "task-flow-dynamic", 1, (f, e) -> Map.of(
            "namespace", f.getNamespace(),
            "flowId", "switch"
        ));
        FlowGraph flowGraph = graphService.flowGraph(flow, Collections.singletonList("root.launch"), execution);

        assertThat(flowGraph.getNodes().size(), is(20));
        assertThat(flowGraph.getEdges().size(), is(23));
        assertThat(flowGraph.getClusters().size(), is(4));
    }