{"record":{"id":"9d9e55e857f95cb7","repo":"floci-io/floci","slug":"validationexception-9d9e55","errorCode":"ValidationException","errorMessage":"Export is required.","messagePattern":"Export is required\\.","errorType":"exception","errorClass":"AwsException","httpStatus":400,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/bcmdataexports/BcmDataExportsJsonHandler.java","lineNumber":143,"sourceCode":"        for (ExportExecution exec : executions) {\n            arr.add(serializeExecution(exec));\n        }\n        return Response.ok(response).build();\n    }\n\n    private Response handleGetExecution(JsonNode request) {\n        String arn = stringOrNull(request, \"ExportArn\");\n        String executionId = stringOrNull(request, \"ExecutionId\");\n        ExportExecution exec = service.getExecution(arn, executionId);\n        ObjectNode response = objectMapper.createObjectNode();\n        response.put(\"ExportArn\", arn);\n        response.set(\"Execution\", serializeExecution(exec));\n        return Response.ok(response).build();\n    }\n\n    private Export parseExport(JsonNode node) {\n        if (node == null || !node.isObject() || node.isEmpty()) {\n            throw new AwsException(\"ValidationException\", \"Export is required.\", 400);\n        }\n        Export e = new Export();\n        e.setName(stringOrNull(node, \"Name\"));\n        e.setDescription(stringOrNull(node, \"Description\"));\n        e.setDataQuery(parseDataQuery(node.path(\"DataQuery\")));\n        e.setDestinationConfigurations(parseDestination(node.path(\"DestinationConfigurations\")));\n        e.setRefreshCadence(parseRefreshCadence(node.path(\"RefreshCadence\")));\n        return e;\n    }\n\n    private DataQuery parseDataQuery(JsonNode node) {\n        if (!node.isObject() || node.isEmpty()) {\n            return null;\n        }\n        DataQuery dq = new DataQuery();\n        dq.setQueryStatement(stringOrNull(node, \"QueryStatement\"));\n        JsonNode tableConfigs = node.path(\"TableConfigurations\");\n        if (tableConfigs.isObject()) {","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/bcmdataexports/BcmDataExportsJsonHandler.java#L125-L161","documentation":"Thrown by Floci's BCM Data Exports emulator when the Export object in the request body is missing, not a JSON object, or empty (parseExport rejects null/non-object/empty nodes with ValidationException 400). This typically guards UpdateExport-style calls where the whole Export payload must be present.","triggerScenarios":"Calling the BCM Data Exports JSON endpoint (e.g. UpdateExport) with a body that omits the Export member, sends \"Export\": {}, sends a scalar/array instead of an object, or sends an empty JSON document.","commonSituations":"SDK request built with an unset Export builder; hand-rolled HTTP requests with malformed JSON; serializing an empty Export object; copying a GetExport response shape but stripping fields.","solutions":["Include a fully populated Export object (Name, DataQuery, DestinationConfigurations, RefreshCadence) in the request.","If using the AWS SDK, build the export via Export.builder() and set it on the request before send.","Validate the payload is a non-empty JSON object before sending when calling the endpoint over raw HTTP.","Check for accidental serialization of an empty Export (e.g. Jackson serializing an unset field as {})."],"exampleFix":"// before\nString body = \"{\\\"Export\\\": {}}\";\n\n// after\nString body = \"{\\\"Export\\\": {\\\"Name\\\":\\\"cost-export\\\",\\\"DataQuery\\\":{\\\"QueryStatement\\\":\\\"SELECT ...\\\",\\\"TableConfigurations\\\":{}},\\\"DestinationConfigurations\\\":{\\\"S3Destination\\\":{\\\"S3Bucket\\\":\\\"my-bucket\\\",\\\"S3Region\\\":\\\"us-east-1\\\",\\\"S3OutputConfigurations\\\":{}}},\\\"RefreshCadence\\\":{\\\"Frequency\\\":\\\"SYNCHRONOUS\\\"}}}\";","handlingStrategy":"validation","validationCode":"JsonNode export = request.path(\"Export\");\nif (export == null || !export.isObject() || export.isEmpty()) {\n    throw new IllegalArgumentException(\"Export must be a non-empty object\");\n}\n// safe to dispatch","typeGuard":"private static boolean isValidExportNode(JsonNode n) {\n    return n != null && n.isObject() && !n.isEmpty() && n.hasNonNull(\"Name\");\n}","tryCatchPattern":null,"preventionTips":["Use the AWS SDK's typed builders so an unset Export fails to compile or serialize correctly.","Add a contract test asserting requests always carry a populated Export.","Keep a JSON schema for the payload and validate before send."],"tags":["bcm-data-exports","validation","request-body","floci","java"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}