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
- Open .onedev-buildspec.yml and fix the YAML syntax/structure; the cause of the exception names the exact line and mapping problem
- Validate the file with the build spec editor UI in OneDev, which reports specific schema errors
- Use an online YAML linter to catch indentation, tabs, and duplicate-key issues
- 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
- Edit specs through the OneDev editor which validates on save
- Run a YAML linter locally; avoid tabs and inconsistent indentation
- Keep spec changes small and validated per commit
- Beware copy-pasted YAML with wrong nesting
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Malformed build spec (import project: {0}, import revision:
- Allocated agent not connected to current server, please retr
- Unknown collection element class (bean: X, property: Y)
- Property 'type' is reserved (class: X)
- Dependency property not found: X
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/0699d9d954c24dc3.
Report an issue: GitHub.