quarkusio/quarkus · warning · WebApplicationException
Id was invalidly set on request.
Error message
Id was invalidly set on request.
What it means
Thrown by the create helper of the schema-mariadb FruitResource when the JSON body of a POST /fruits request already contains an id. The endpoint only supports creating new entities where the database generates the id, so a pre-set id is rejected with HTTP 422 (Unprocessable Entity) to prevent accidental upsert-like behavior.
Source
Thrown at integration-tests/hibernate-orm-tenancy/schema-mariadb/src/main/java/io/quarkus/it/hibernate/multitenancy/fruit/FruitResource.java:91
}
@POST
@Transactional
@Path("fruits")
public Response createDefault(@NotNull Fruit fruit) {
return create(fruit);
}
@POST
@Transactional
@Path("{tenant}/fruits")
public Response createTenant(@NotNull Fruit fruit) {
return create(fruit);
}
private Response create(@NotNull Fruit fruit) {
if (fruit.getId() != null) {
throw new WebApplicationException("Id was invalidly set on request.", 422);
}
LOG.debugv("Create {0}", fruit.getName());
entityManager.persist(fruit);
return Response.ok(fruit).status(201).build();
}
@PUT
@Path("fruits/{id}")
@Transactional
public Fruit updateDefault(@PathParam("id") int id, @NotNull Fruit fruit) {
return update(id, fruit);
}
@PUT
@Path("{tenant}/fruits/{id}")
@Transactional
public Fruit updateTenant(@PathParam("id") int id, @NotNull Fruit fruit) {
return update(id, fruit);View on GitHub (pinned to e1c734241f)
Solutions
- Strip/null the id field before POSTing: fruit.setId(null)
- Use a dedicated DTO/request object without an id for creation
- If you meant to update an existing fruit, use PUT /fruits/{id} instead of POST
- In tests, build a fresh Fruit (new Fruit("name")) rather than reusing one loaded from the DB
Example fix
// before
Fruit existing = given().get("/fruits/1").as(Fruit.class);
given().body(existing).post("/fruits"); // 422 - id already set
// after
Fruit toCreate = new Fruit(existing.getName()); // id is null
given().contentType(ContentType.JSON).body(toCreate).post("/fruits"); // 201 Defensive patterns
Strategy: validation
Validate before calling
if (fruit.getId() != null) {
fruit = new Fruit(fruit.getName()); // drop id before POST
}
given().contentType(ContentType.JSON).body(fruit).post("/fruits"); Type guard
static Fruit withoutId(Fruit f) {
return f.getId() == null ? f : new Fruit(f.getName());
} Try / catch
try {
given().body(fruit).post("/fruits");
} catch (WebApplicationException e) {
if (e.getResponse().getStatus() == 422) { fruit.setId(null); /* retry POST */ }
else throw e;
} Prevention
- 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
When it happens
Trigger: POSTing a Fruit payload that includes "id": <value> (non-null), e.g. client echoes back a previously fetched fruit object instead of sending a fresh one.
Common situations: Client deserializes a GET response into the same object it then re-POSTs; tests reusing a fixture Fruit instance that already has an id; frontend form bound to an existing entity when the user intended 'new'.
Related errors
- Fruit Name was not set on request.
- Extra steps left over
- Unknown start character for json value: %s
- Id was invalidly set on request.
- Fruit Name was not set on request.
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/39cf398d0527ff52.
Report an issue: GitHub.