theonedev/onedev · error · BuildSpecParseException

Malformed build spec

Error message

Malformed build spec

What it means

BuildSpec.load parses a build spec string (.onedev-buildspec.yml content) into a BuildSpec bean via YAML deserialization. Any parse or binding failure is wrapped in a BuildSpecParseException with message 'Malformed build spec', keeping the original cause. Legacy XML-format specs are migrated first via XmlBuildSpecMigrator.

Source

Thrown at server-core/src/main/java/io/onedev/server/buildspec/BuildSpec.java:82

@Editable
@ClassValidating
public class BuildSpec implements Serializable, Validatable {

	private static final long serialVersionUID = 1L;
	
	private static final LoadingCache<String, byte[]> parseCache =  
			CacheBuilder.newBuilder().softValues().build(new CacheLoader<String, byte[]>() {
	        
		@Override
        public byte[] load(String key) {
			String buildSpecString = key;
			if (buildSpecString.trim().startsWith("<?xml"))
				buildSpecString = XmlBuildSpecMigrator.migrate(buildSpecString);
			try {
				return SerializationUtils.serialize(VersionedYamlDoc.fromYaml(buildSpecString).toBean(BuildSpec.class));
			} catch (Exception e) {
				throw new BuildSpecParseException("Malformed build spec", e);
			}
        }
	        
	});
	
	public static final String BLOB_PATH = ".onedev-buildspec.yml";
	
	private static final String PROP_JOBS = "jobs";
	
	private static final String PROP_SERVICES = "services";
	
	private static final String PROP_STEP_TEMPLATES = "stepTemplates";
	
	private static final String PROP_PROPERTIES = "properties";
	
	private static final String PROP_IMPORTS = "imports";
	
	private List<Job> jobs = new ArrayList<>();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Open .onedev-buildspec.yml and fix the YAML syntax/structure; the cause of the exception names the exact line and mapping problem
  2. Validate the file with the build spec editor UI in OneDev, which reports specific schema errors
  3. Use an online YAML linter to catch indentation, tabs, and duplicate-key issues
  4. If the project predates YAML build specs, re-save the spec through the UI so migration runs cleanly

Example fix

# before (invalid: job name missing, bad indentation)
jobs:
- steps: !CheckoutStep
# after
jobs:
- name: build
  steps:
  - !CheckoutStep
    with:
      repository: self
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    new org.yaml.snakeyaml.Yaml().load(buildSpecYaml);
} catch (Exception e) {
    return "Invalid YAML: " + e.getMessage();
}

Try / catch

try {
    BuildSpec spec = project.getBuildSpec(commit);
} catch (BuildSpecParseException e) {
    logger.error("Bad .onedev-buildspec.yml: {}", e.getMessage(), e.getCause());
}

Prevention

When it happens

Trigger: Committing a .onedev-buildspec.yml with invalid YAML syntax, wrong types (e.g. a string where a list is expected), unknown property names, or invalid structure that fails to map onto the BuildSpec class.

Common situations: Hand-editing the build spec file with YAML indentation errors; using tabs instead of spaces; renaming jobs/steps fields to unsupported names; older projects still having XML-era specs that fail migration; copy-pasting partial YAML snippets.

Understand the failure class

Related errors


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