theonedev/onedev · error · ExplicitException

Malformed build spec (import project: {0}, import revision:

Error message

Malformed build spec (import project: {0}, import revision: {1})

What it means

When a build spec imports another project's build spec via an `imports` entry, OneDev resolves the imported project's build spec at the given revision. If parsing that build spec fails (BuildSpecParseException), Import.getBuildSpec wraps the failure in an ExplicitException with the importing project path and revision so the user sees exactly which import is broken.

Source

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

						projectPath, revision, e.getMessage());
				throw new ExplicitException(errorMessage);
			}
			if (!subject.isPermitted(new ProjectPermission(project, new ReadCode())) 
					&& !project.isPermittedByLoginUser(new ReadCode())) {
				String errorMessage = MessageFormat.format(
						_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());

View on GitHub (pinned to d44925c47c)

Solutions

  1. Open the imported project (projectPath in the message) at the given revision and fix the build spec syntax errors reported by its spec editor/validation.
  2. Change the import revision to a commit where the imported project's build spec parses correctly.
  3. Validate the imported spec standalone (project build spec page shows parse errors) before re-running the importing build.

Example fix

// Imported project's .onedev-buildspec (before - bad indentation/unknown key)
jobs:
- name: build
  steps:
  - !CheckoutStep
    bol: true   # typo
// after
jobs:
- name: build
  steps:
  - !CheckoutStep
    forceCheckout: true
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on an import, validate the imported spec resolves & parses
try {
    var imported = new Import(importProjectPath, importRevision);
    imported.getBuildSpec(); // throws ExplicitException on parse failure
} catch (ExplicitException e) {
    // surface e.getMessage() to the user
}

Try / catch

try { import.getBuildSpec(); } catch (ExplicitException e) { log.error("Broken import spec: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling Import.getBuildSpec (via Import.buildSpec) where project.getBuildSpec(commit) throws BuildSpecParseException — i.e. the .onedev-buildspec file in the imported project at the given revision has syntax errors, unknown job/step names, or invalid YAML structure.

Common situations: Imported project committed a broken build spec; the referenced revision predates a fix; local edits to the build spec were committed with YAML/indentation mistakes; a step class name was mistyped or a plugin step was removed in the imported project.

Understand the failure class

Related errors


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