theonedev/onedev · error · ExplicitException
No applicable executor discovered for current job
Error message
No applicable executor discovered for current job
What it means
Thrown by DefaultJobService.getJobExecutor when no explicit executor is named and none of the globally configured, enabled job executors pass isApplicable for the current build. OneDev iterates all executors in order, logs 'Discovered ...' for the first match, and throws this ExplicitException only after exhausting the list.
Source
Thrown at server-core/src/main/java/io/onedev/server/job/DefaultJobService.java:548
return settingService.getJobExecutors().stream()
.filter(it -> it.isEnabled() && isApplicable(build, it))
.findFirst()
.orElseThrow(() -> new ExplicitException("No applicable job executor"));
} else {
jobLogger.log("No job executor defined, auto-discovering...");
List<JobExecutorDiscoverer> discoverers = new ArrayList<>(OneDev.getExtensions(JobExecutorDiscoverer.class));
discoverers.sort(Comparator.comparing(JobExecutorDiscoverer::getOrder));
for (var discoverer : discoverers) {
JobExecutor jobExecutor = discoverer.discover();
if (jobExecutor != null) {
jobExecutor.setName("auto-discovered");
if (isApplicable(build, jobExecutor)) {
jobLogger.log("Discovered " + EditableUtils.getDisplayName(jobExecutor.getClass()).toLowerCase());
return jobExecutor;
}
}
}
throw new ExplicitException("No applicable executor discovered for current job");
}
}
}
private Future<Boolean> execute(Build build) {
String jobToken = build.getToken();
JobVariableInterpolator interpolator = new JobVariableInterpolator(build, build.getParamCombination());
TaskLogger jobLogger = logService.newLogger(build.getLoggingSupport());
String jobExecutorName = interpolator.interpolate(build.getJob().getJobExecutor());
JobExecutor jobExecutor = interpolator.interpolateProperties(getJobExecutor(build, jobExecutorName, jobLogger));
String sequentialGroup = interpolator.interpolate(build.getJob().getSequentialGroup());
String sequentialKey;
if (sequentialGroup != null)
sequentialKey = jobExecutorName + ":" + sequentialGroup;
else
sequentialKey = null;
Long projectId = build.getProject().getId();View on GitHub (pinned to d44925c47c)
Solutions
- Enable at least one job executor in Server Setting > Job Executors and ensure its criteria match this job.
- Register/bring online the required runners (docker host, k8s cluster, remote agent).
- Broaden executor criteria so they apply to this project/branch/job.
- Name a specific executor in the build spec if auto-discovery ordering is the problem.
Example fix
// Admin: Server Setting > Job Executors > Add Executor // e.g. add a Docker Executor with project criteria '*' and enable it, // then verify a runner is registered: // Admin > Runners/Agents > Add Runner, use the token in your docker agent container
Defensive patterns
Strategy: validation
Validate before calling
// Java: verify at least one enabled executor applies before queueing jobs
boolean anyApplicable = OneDev.getInstance(SettingService.class)
.getJobExecutors().stream()
.anyMatch(it -> it.isEnabled());
if (!anyApplicable) {
throw new IllegalStateException("No enabled job executors configured");
} Try / catch
try {
jobService.submit(build);
} catch (ExplicitException e) {
if (e.getMessage().contains("No applicable executor")) {
// alert admins to enable/register executors; retry after config fix
}
} Prevention
- Keep at least one catch-all enabled executor with broad criteria
- Monitor runner/agent connectivity so capacity-backed executors stay applicable
- After instance migration, verify executor configuration before enabling CI
When it happens
Trigger: Submitting a job when settingService.getJobExecutors() is non-empty but every executor is either disabled or not applicable (wrong project/branch/job criteria, no registered runners), or the executor list is empty of usable entries for the job.
Common situations: Fresh OneDev instance with default executors only and the job requires Docker/K8s; all runners offline; executors all scoped to other projects/branches; admin disabled executors during maintenance while CI jobs keep being submitted.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Specified job executor '" + jobExecutorName + "' is disabled
- Specified job executor '" + jobExecutorName + "' is not appl
- Duplicate dependency build '" + dependencyBuild.getReference
- Unrecognized command:
- Unable to discover cluster ip from database connection url:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/ee786775a628cd9a.
Report an issue: GitHub.