{"record":{"id":"4d5ea975ec8f582f","repo":"quarkusio/quarkus","slug":"extra-steps-left-over","errorCode":null,"errorMessage":"Extra steps left over","messagePattern":"Extra steps left over","errorType":"exception","errorClass":"BuildException","httpStatus":null,"severity":"error","filePath":"core/builder/src/main/java/io/quarkus/builder/Execution.java","lineNumber":149,"sourceCode":"                intr = true;\n            } finally {\n                if (intr)\n                    Thread.currentThread().interrupt();\n            }\n        for (Diagnostic diagnostic : diagnostics) {\n            if (diagnostic.getLevel() == Diagnostic.Level.ERROR) {\n                BuildException failed = new BuildException(\"Build failed due to errors\", diagnostic.getThrown(),\n                        Collections.unmodifiableList(diagnostics));\n                for (Diagnostic i : diagnostics) {\n                    if (i.getThrown() != null && i.getThrown() != diagnostic.getThrown()) {\n                        failed.addSuppressed(i.getThrown());\n                    }\n                }\n                throw failed;\n            }\n        }\n        if (lastStepCount.get() > 0)\n            throw new BuildException(\"Extra steps left over\", Collections.emptyList());\n\n        long duration = max(0, System.nanoTime() - start);\n        metrics.buildFinished(TimeUnit.NANOSECONDS.toMillis(duration));\n        return new BuildResult(singles, multis, finalIds, Collections.unmodifiableList(diagnostics),\n                duration, metrics, chain.getClassLoader());\n    }\n\n    EnhancedQueueExecutor getExecutor() {\n        return executor;\n    }\n\n    String getBuildTargetName() {\n        return buildTargetName;\n    }\n\n    void setErrorReported() {\n        errorReported.compareAndSet(false, true);\n    }","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/builder/src/main/java/io/quarkus/builder/Execution.java#L131-L167","documentation":"RootResource.posts (POST, text/plain) throws \"No post data\" when the JAX-RS request entity resolves to null. This happens when the POST body is absent, empty, or has a Content-Type inconsistent with @Consumes(TEXT_PLAIN), so the String parameter is never populated.","triggerScenarios":"POST to the resource with an empty body, no body at all, or a Content-Type other than text/plain (e.g. none or application/json), causing data == null.","commonSituations":"Test client sending POST without a body; curl forgetting -d or -H 'Content-Type: text/plain'; framework/quarkus-rest clients serializing nothing; gateway stripping the body.","solutions":["Send a non-empty text/plain body with the POST request (e.g. curl -H 'Content-Type: text/plain' -d 'payload' ...).","Ensure the Content-Type header is text/plain to match @Consumes.","Null-check data before use and return 400 instead of RuntimeException.","Verify no filter/proxy removes the request body."],"exampleFix":"// before\npublic String posts(String data, @Context SecurityContext sec) {\n    if (data == null) {\n        throw new RuntimeException(\"No post data\");\n    }\n// after\ncurl -H \"Content-Type: text/plain\" -d \"hello\" http://localhost:8080/\n// and/or in code: return Response.status(400).build() when data == null","handlingStrategy":"validation","validationCode":"if (fruit.getId() != null) {\n    fruit = new Fruit(fruit.getName()); // drop id before POST\n}\ngiven().contentType(ContentType.JSON).body(fruit).post(\"/fruits\");","typeGuard":"static Fruit withoutId(Fruit f) {\n    return f.getId() == null ? f : new Fruit(f.getName());\n}","tryCatchPattern":"try {\n    given().body(fruit).post(\"/fruits\");\n} catch (WebApplicationException e) {\n    if (e.getResponse().getStatus() == 422) { fruit.setId(null); /* retry POST */ }\n    else throw e;\n}","preventionTips":["Use a create-DTO without an id field for POST bodies","Never re-POST an entity fetched via GET; clone it and null the id","Distinguish POST (create) vs PUT (update) semantics in clients","Assert 201 (not 422) in tests that create fruit"],"tags":["rest","jaxrs","request-body","validation"],"backgroundTag":"missing-request-body","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}