theonedev/onedev · error · ExplicitException

Build spec not defined (import project: {0}, import revision

Error message

Build spec not defined (import project: {0}, import revision: {1})

What it means

Import.getBuildSpec returns null when the imported project at the given revision defines no build spec at all (no .onedev-buildspec file). OneDev converts that null into an ExplicitException naming the import project and revision, since importing a non-existent spec cannot proceed.

Source

Thrown at server-core/src/main/java/io/onedev/server/buildspec/Import.java:186

						_T("Code read permission is required to import build spec (import project: {0}, import revision: {1})"), 
						projectPath, revision);
				throw new ExplicitException(errorMessage);
			}
			
			RevCommit commit = getCommit();
			try {
				buildSpec = project.getBuildSpec(commit);
			} catch (BuildSpecParseException e) {
				String errorMessage = MessageFormat.format(
						_T("Malformed build spec (import project: {0}, import revision: {1})"), 
						projectPath, revision);
				throw new ExplicitException(errorMessage);
			}
			if (buildSpec == null) {
				String errorMessage = MessageFormat.format(
						_T("Build spec not defined (import project: {0}, import revision: {1})"), 
						projectPath, revision);
				throw new ExplicitException(errorMessage);
			}
			
		}
		return buildSpec;
	}
	
	@Override
	public boolean isValid(ConstraintValidatorContext context) {
		try {
			var commit = getCommit();
			if (IMPORT_CHAIN.get().contains(commit.name())) {
				List<String> circular = new ArrayList<>(IMPORT_CHAIN.get());
				circular.add(commit.name());
				String errorMessage = MessageFormat.format(
						_T("Circular build spec imports ({0})"), circular);
				context.disableDefaultConstraintViolation();
				context.buildConstraintViolationWithTemplate(errorMessage).addConstraintViolation();
				return false;

View on GitHub (pinned to d44925c47c)

Solutions

  1. Add a .onedev-buildspec file to the imported project at the referenced revision.
  2. Point the import revision at a commit that actually contains the build spec.
  3. If the spec lives at a custom path, set it in the imported project's Build Specs setting so getBuildSpec finds it.

Example fix

// before: import revision "old-branch" has no spec
imports:
- project: shared/pipeline
  revision: old-branch
// after: use a revision containing .onedev-buildspec
imports:
- project: shared/pipeline
  revision: main
Defensive patterns

Strategy: validation

Validate before calling

// Check the target commit actually has a build spec before importing
var commit = project.getRevCommit(revision, false);
if (commit == null || project.getBuildSpec(commit) == null)
    throw new IllegalStateException("No build spec at " + revision);

Try / catch

try { import.getBuildSpec(); } catch (ExplicitException e) { fallbackToLocalSpec(e.getMessage()); }

Prevention

When it happens

Trigger: An `imports` entry in a build spec references a project/revision pair where getBuildSpec(commit) returns null — the commit has no .onedev-buildspec file, or the build spec is registered under a different path/setting.

Common situations: Typo in the import project path resolved to a repo without a spec; imported revision predates introduction of the build spec; repo stores its spec at a custom location and the project build-spec setting was never configured.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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