theonedev/onedev · error · ExplicitException

Specified job executor '" + jobExecutorName + "' is not appl

Error message

Specified job executor '" + jobExecutorName + "' is not applicable for current job

What it means

Thrown by DefaultJobService.getJobExecutor when the job spec names an enabled executor whose isApplicable(build, jobExecutor) check fails — i.e., the executor's criteria (project, job name, branch/tag, ref filters, runner capability) do not match the current build. The executor exists and is enabled, but it cannot run this particular job.

Source

Thrown at server-core/src/main/java/io/onedev/server/job/DefaultJobService.java:525

				return false;
			}
		} else {
			return executor.isApplicable(new JobMatchContext(
					build.getProject(), null, build.getCommitId(),
					build.getJobName()));
		}
	}

	private JobExecutor getJobExecutor(Build build, @Nullable String jobExecutorName, TaskLogger jobLogger) {
		if (jobExecutorName != null) {
			var jobExecutor = settingService.getJobExecutors().stream()
				.filter(it -> it.getName().equals(jobExecutorName))
				.findFirst()
				.orElseThrow(() -> new ExplicitException("Unable to find specified job executor '" + jobExecutorName + "'"));
			if (!jobExecutor.isEnabled())
				throw new ExplicitException("Specified job executor '" + jobExecutorName + "' is disabled");
			else if (!isApplicable(build, jobExecutor))
				throw new ExplicitException("Specified job executor '" + jobExecutorName + "' is not applicable for current job");
			else 
				return jobExecutor;
		} else {
			if (!settingService.getJobExecutors().isEmpty()) {
				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());

View on GitHub (pinned to d44925c47c)

Solutions

  1. Broaden the executor's criteria in Server Setting > Job Executors (project/branch/job filters) to include this job.
  2. Change the job spec to name an executor whose criteria match this build.
  3. Remove the explicit executor name to let auto-discovery pick any applicable enabled executor.
  4. Register the required runner/agent so the executor's capacity requirements are satisfied.

Example fix

// before: executor scoped to main branch only, job on feature branch
// after (build spec): omit executor name for auto-discovery
jobs:
  - name: Build
    steps: !<CommandLine>
      shellScript: mvn package
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the named executor's criteria include this project/branch/job
// before referencing it in .onedev-buildspec.yml:
// Admin > Job Executors > <name> : check project/branch/job criteria
// and required capabilities for the job being submitted

Try / catch

try {
    jobService.submit(build);
} catch (ExplicitException e) {
    if (e.getMessage().contains("is not applicable")) {
        // broaden executor criteria or drop the explicit executor name
    }
}

Prevention

When it happens

Trigger: Specifying 'executor: <name>' where that executor defines applicability criteria (e.g., restricted to certain projects, branches, job names, or requires a registered runner) that the current build/job does not satisfy; then jobExecutor -> getJobExecutor throws.

Common situations: Executor narrowed to main branch while job runs on a feature branch; executor scoped to specific projects; spec copied from another project; executor requires a docker image field the job doesn't set; runners unregistered so capacity criteria fail.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/38ba3fe6591339c9. Report an issue: GitHub.