kestra-io/kestra · error · IllegalArgumentException

Too many flow found, need 1, found {}

Error message

Too many flow found, need 1, found {}

What it means

Thrown by 'kestra flow test' when the loader finds more than one flow from the provided file/path. The command is designed to test exactly one flow; after repositoryLoader.load and flowRepository.findAllForAllTenants(), if the result size is not 1 it throws IllegalArgumentException naming the count found. This usually means the path is a directory containing multiple flow files.

Source

Thrown at cli/src/main/java/io/kestra/cli/commands/flows/FlowTestCommand.java:105

        DispatchQueueInterface<ExecutionCommand> executionCommandQueue = applicationContext.getBean(DispatchQueueInterface.class, Qualifiers.byTypeArguments(ExecutionCommand.class));

        Map<String, Object> inputs = new HashMap<>();

        for (int i = 0; i < this.inputs.size(); i = i + 2) {
            if (this.inputs.size() <= i + 1) {
                throw new CommandLine.ParameterException(this.spec.commandLine(), "Invalid key pair value for inputs");
            }

            inputs.put(this.inputs.get(i), this.inputs.get(i + 1));
        }

        try (StandAloneRunner runner = applicationContext.createBean(StandAloneRunner.class);) {
            runner.run();
            repositoryLoader.load(tenantService.getTenantId(tenantId), file.toFile());

            List<Flow> all = flowRepository.findAllForAllTenants();
            if (all.size() != 1) {
                throw new IllegalArgumentException("Too many flow found, need 1, found " + all.size());
            }

            var flow = all.getFirst();
            var createCommand = Create.of(flow.toFlowId()).withInputsFromReader((executionId) -> flowInputOutput.readExecutionInputs(flow, executionId, inputs));
            executionCommandQueue.emit(
                createCommand
            );
            Execution terminated = await().atMost(Duration.ofHours(1)).until(
                () -> executionRepository.findById(tenantService.getTenantId(tenantId), createCommand.executionId()).orElse(null),
                e -> e != null && e.getState().isTerminated()
            );
            stdOut("Successfully executed the flow with execution %s in state %s", terminated.getId(), terminated.getState().getCurrent());
        } catch (ConstraintViolationException e) {
            throw new CommandLine.ParameterException(this.spec.commandLine(), e.getMessage());
        } catch (IOException e) {
            throw new IllegalStateException(e);
        } finally {
            applicationContext.getProperty("kestra.storage.local.base-path", Path.class)

View on GitHub (pinned to 823fada927)

Solutions

  1. Point --file at a single flow YAML file, not a directory.
  2. Ensure the YAML contains exactly one flow definition (no multi-document separators).
  3. If testing in a populated repo, scope by tenant/namespace or run against an empty repository.
  4. Use a dedicated test workspace containing only the target flow.

Example fix

# before: directory with several flows
kestra flow test ./flows/
# after: single file
kestra flow test ./flows/myflow.yaml
Defensive patterns

Strategy: validation

Validate before calling

List<Flow> all = flowRepository.findAllForAllTenants();
if (all.size() != 1) {
  throw new IllegalStateException('Expected exactly one flow, found ' + all.size());
}

Prevention

When it happens

Trigger: repositoryLoader.load(tenantId, file) loads multiple flows (e.g. a directory or a multi-doc YAML), findAllForAllTenants().size() != 1, and IllegalArgumentException is thrown with the actual count.

Common situations: User passes a directory instead of a single flow file, a YAML file contains multiple flow documents, the path glob expanded to several files, or pre-existing flows in the repository are counted alongside the new one.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/b7477ef864f12e94. Report an issue: GitHub.