{"record":{"id":"0699d9d954c24dc3","repo":"theonedev/onedev","slug":"malformed-build-spec","errorCode":null,"errorMessage":"Malformed build spec","messagePattern":"Malformed build spec","errorType":"exception","errorClass":"BuildSpecParseException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/buildspec/BuildSpec.java","lineNumber":82,"sourceCode":"\n@Editable\n@ClassValidating\npublic class BuildSpec implements Serializable, Validatable {\n\n\tprivate static final long serialVersionUID = 1L;\n\t\n\tprivate static final LoadingCache<String, byte[]> parseCache =  \n\t\t\tCacheBuilder.newBuilder().softValues().build(new CacheLoader<String, byte[]>() {\n\t        \n\t\t@Override\n        public byte[] load(String key) {\n\t\t\tString buildSpecString = key;\n\t\t\tif (buildSpecString.trim().startsWith(\"<?xml\"))\n\t\t\t\tbuildSpecString = XmlBuildSpecMigrator.migrate(buildSpecString);\n\t\t\ttry {\n\t\t\t\treturn SerializationUtils.serialize(VersionedYamlDoc.fromYaml(buildSpecString).toBean(BuildSpec.class));\n\t\t\t} catch (Exception e) {\n\t\t\t\tthrow new BuildSpecParseException(\"Malformed build spec\", e);\n\t\t\t}\n        }\n\t        \n\t});\n\t\n\tpublic static final String BLOB_PATH = \".onedev-buildspec.yml\";\n\t\n\tprivate static final String PROP_JOBS = \"jobs\";\n\t\n\tprivate static final String PROP_SERVICES = \"services\";\n\t\n\tprivate static final String PROP_STEP_TEMPLATES = \"stepTemplates\";\n\t\n\tprivate static final String PROP_PROPERTIES = \"properties\";\n\t\n\tprivate static final String PROP_IMPORTS = \"imports\";\n\t\n\tprivate List<Job> jobs = new ArrayList<>();","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/buildspec/BuildSpec.java#L64-L100","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before (invalid: job name missing, bad indentation)\njobs:\n- steps: !CheckoutStep\n# after\njobs:\n- name: build\n  steps:\n  - !CheckoutStep\n    with:\n      repository: self","handlingStrategy":"try-catch","validationCode":"try {\n    new org.yaml.snakeyaml.Yaml().load(buildSpecYaml);\n} catch (Exception e) {\n    return \"Invalid YAML: \" + e.getMessage();\n}","typeGuard":null,"tryCatchPattern":"try {\n    BuildSpec spec = project.getBuildSpec(commit);\n} catch (BuildSpecParseException e) {\n    logger.error(\"Bad .onedev-buildspec.yml: {}\", e.getMessage(), e.getCause());\n}","preventionTips":["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"],"tags":["buildspec","yaml","ci"],"backgroundTag":"yaml-parse-error","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}