theonedev/onedev · error · ExplicitException

This workspace can only be provisioned by docker provisioner

Error message

This workspace can only be provisioned by docker provisioner

What it means

ServerShellProvisioner.provision() refuses to provision a workspace whose job spec is marked runInContainer. This provisioner runs jobs directly on the server shell (no containers), so a spec requesting container execution must be handled by the docker provisioner instead. The check runs via checkApplicable()+spec inspection before any provisioning work begins.

Source

Thrown at server-plugin/server-plugin-provisioner-servershell/src/main/java/io/onedev/server/plugin/provisioner/servershell/ServerShellProvisioner.java:140

	public String getApplicableProjects() {
		return applicableProjects;
	}

	public void setApplicableProjects(String applicableProjects) {
		this.applicableProjects = applicableProjects;
	}
	
	@SuppressWarnings("unused")
	private static List<InputSuggestion> suggestProjects(String matchWith) {
		return SuggestionUtils.suggestProjectPaths(matchWith);
	}

	@Override
	public WorkspaceRuntime provision(WorkspaceContext context, TaskLogger workspaceLogger) {
		checkApplicable();

		if (context.getSpec().isRunInContainer()) 
			throw new ExplicitException("This workspace can only be provisioned by docker provisioner");

		var serverAddress = getClusterService().getLocalServerAddress();
		workspaceLogger.log("Provisioning workspace on server '" + serverAddress + "'...");
		persistServerAddress(context.getWorkspaceId(), serverAddress);		
		
		var workspaceDir = getWorkspaceDir(context);
		FileUtils.createDir(workspaceDir);
		setupRepository(context, workspaceDir.getAbsolutePath(), workspaceLogger);

		var trustCertsFile = new File(workspaceDir, "trust-certs.pem");

		var workDir = getWorkDir(context);
		var envVars = buildEnvVars(
				context.getSpec().getEnvVars().stream()
						.collect(toMap(EnvVar::getName, it -> it.isSecret() ? it.getSecretValue() : it.getValue())),
				context.getServerUrl(), context.getToken(), 
				trustCertsFile.exists()? trustCertsFile.getAbsolutePath(): null,
				workDir.getAbsolutePath());

View on GitHub (pinned to d44925c47c)

Solutions

  1. Remove the 'run in container' setting from the job spec, or uncheck the container option in the pipeline/agent spec UI
  2. Change the agent/runner handling this workspace to use the Docker provisioner instead of Server Shell
  3. Use a different executor/pool assignment so containerized specs never land on server-shell agents

Example fix

// before (pipeline spec)
runInContainer: true
image: node:20
// after
runInContainer: false
# or assign job to a docker-provisioned agent
Defensive patterns

Strategy: validation

Validate before calling

if (spec.isRunInContainer()) throw new IllegalStateException("Assign this job to a docker-provisioned agent or disable runInContainer");

Try / catch

try { provisioner.provision(ctx, logger); } catch (ExplicitException e) { logger.log(e.getMessage()); }

Prevention

When it happens

Trigger: Calling provision() with a WorkspaceContext whose spec.isRunInContainer() returns true — i.e. the CI job/agent spec declares 'run in container' while the assigned agent uses the Server Shell provisioner.

Common situations: A project pipeline was written for docker-based agents but is routed to a server-shell agent pool; a spec template was copied from a docker/K8s agent setup onto a bare-server agent; the agent's provisioner was switched from docker to server shell after the spec was authored.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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