{"record":{"id":"db708086b67ad752","repo":"floci-io/floci","slug":"invalidinputexception","errorCode":"InvalidInputException","errorMessage":"Buildspec content is empty","messagePattern":"Buildspec content is empty","errorType":"exception","errorClass":"AwsException","httpStatus":400,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/codebuild/BuildspecParser.java","lineNumber":42,"sourceCode":"            List<String> installCommands,\n            List<String> preBuildCommands,\n            List<String> buildCommands,\n            List<String> postBuildCommands,\n            ParsedArtifacts artifacts\n    ) {}\n\n    record ParsedArtifacts(\n            String type,\n            List<String> files,\n            String baseDirectory,\n            boolean discardPaths,\n            String name,\n            String packaging\n    ) {}\n\n    static ParsedBuildspec parse(String content) {\n        if (content == null || content.isBlank()) {\n            throw new AwsException(\"InvalidInputException\", \"Buildspec content is empty\", 400);\n        }\n        try {\n            JsonNode root = YAML.readTree(content);\n\n            JsonNode envNode = root.path(\"env\");\n            Map<String, String> envVars = parseStringMap(envNode.path(\"variables\"));\n            Map<String, String> paramStore = parseStringMap(envNode.path(\"parameter-store\"));\n            Map<String, String> secretsMgr = parseStringMap(envNode.path(\"secrets-manager\"));\n\n            JsonNode phases = root.path(\"phases\");\n            List<String> install = parseCommands(phases.path(\"install\"));\n            List<String> preBuild = parseCommands(phases.path(\"pre_build\"));\n            List<String> build = parseCommands(phases.path(\"build\"));\n            List<String> postBuild = parseCommands(phases.path(\"post_build\"));\n\n            ParsedArtifacts artifacts = parseArtifacts(root.path(\"artifacts\"));\n\n            return new ParsedBuildspec(envVars, paramStore, secretsMgr,","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/codebuild/BuildspecParser.java#L24-L60","documentation":"Thrown by BuildspecParser.parse when the buildspec string passed to it is null or contains only whitespace. Floci calls this parser during StartBuild after resolving the buildspec from the project's source.buildspec field, an explicit buildspecOverride, or a buildspec.yml/buildspec.yaml file in the downloaded source. It surfaces as an InvalidInputException HTTP 400, mirroring AWS CodeBuild's rejection of empty buildspec content.","triggerScenarios":"Calling StartBuild with a buildspecOverride that is an empty string; creating a project whose source.buildspec is set to \"\" or whitespace; a source checkout whose buildspec.yml exists but is empty (0 bytes or only whitespace), which Floci reads and passes to the parser.","commonSituations":"Templates or CDK constructs that interpolate a buildspec variable that is unset; CI pipelines that generate buildspec.yml dynamically and emit an empty file on failure; passing the wrong field (e.g. buildspecVersion) so the intended content never reaches the parser.","solutions":["Provide non-blank buildspec content: either set source.buildspec on the project, pass buildspecOverride in StartBuild, or commit a non-empty buildspec.yml at the source root","If generating the buildspec in CI, assert the file is non-empty before triggering StartBuild","Verify you are reading the file you think you are (buildspec.yml vs buildspec.yaml in a subdirectory is ignored; only workspace root is checked)"],"exampleFix":"# before\naws codebuild start-build --project-name demo --buildspec-override ''\n\n# after\ncat > buildspec.yml <<'EOF'\nversion: 0.2\nphases:\n  build:\n    commands:\n      - echo building\nEOF\naws codebuild start-build --project-name demo","handlingStrategy":"validation","validationCode":"// Java, AWS SDK v2 - before StartBuild\nString buildspec = resolveBuildspec(project, override); // project.source().buildspec(), override, or file read\nif (buildspec == null || buildspec.isBlank()) {\n    throw new IllegalArgumentException(\"Buildspec is empty - set source.buildspec, buildspecOverride, or commit buildspec.yml\");\n}","typeGuard":null,"tryCatchPattern":"// Catch as InvalidInputException from the SDK; empty buildspec is a caller bug - fail fast, do not retry\ncatch (InvalidInputException e) {\n    if (e.getMessage().contains(\"empty\")) throw new IllegalStateException(\"Buildspec missing: \" + e.getMessage(), e);\n    throw e;\n}","preventionTips":["Never pass buildspecOverride as empty string; omit the field instead","Assert generated buildspec.yml is non-empty in CI before triggering builds","For NO_SOURCE projects always set source.buildspec inline"],"tags":["codebuild","buildspec","validation","yaml"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}