Skip to content

fix: Remove the server.error.include-message key Spring Boot 4 no longer binds - EXO-91152 - #668

Merged
boubaker merged 1 commit into
developfrom
fix/EXO-91152-error-message
Oct 12, 2026
Merged

boubaker merged 1 commit into
developfrom
fix/EXO-91152-error-message

Conversation

@boubaker

@boubaker boubaker commented Oct 9, 2026

Copy link
Copy Markdown
Member

Symptom: webapps/src/main/resources/task.properties sets server.error.include-message=always, a key Spring Boot 4 no longer binds.

Cause: Spring Boot 4 moved the server.error.* group to spring.web.error.*, so the key does nothing.

Fix: Remove the dead key. This WAR imports application-common.properties, where Meeds-io/portal#1336 sets the live spring.web.error.include-message and keeps a 4xx refusal's explicit reason in the error body. No runtime change, since the removed key bound to nothing, and no merge-order constraint against Meeds-io/portal#1336.

Knowledge: Meeds-io/eng-standards#379

This change is classified N1 (Architects Lead, 2026-10-09; computed on the delivery head 5ae991fb4): its approver must be an Archi/Dev who knows it is N1, not an approval on AI review alone, and author ≠ approver.

🤖 Generated with Claude Code

…ger binds - EXO-91152

Spring Boot 4 moved the server.error.* group to spring.web.error.*, so this
key bound to nothing. The platform's application-common.properties, which
this WAR imports, now sets the live spring.web.error.include-message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@boubaker
boubaker requested a review from ahamdi October 9, 2026 16:13
@github-actions github-actions Bot added the partialCIBuild Perform Partial CI Build label Oct 9, 2026
@sonarqubecloud

sonarqubecloud Bot commented Oct 9, 2026

Copy link
Copy Markdown

boubaker added a commit to Meeds-io/portal that referenced this pull request Oct 12, 2026
…ody - EXO-91152 (#1336)

**Symptom**: A Spring MVC resource that refuses with
`ResponseStatusException(HttpStatus.BAD_REQUEST, "some.messageCode")`
answers an error body without `message`, so a client that maps `message`
to a translated label can only show a generic error.

**Cause**: Spring Boot 4 moved the `server.error.*` group to
`spring.web.error.*` (`WebProperties#getError`). The
`server.error.include-message=always` in `application-common.properties`
binds to nothing, so `BasicErrorController` keeps
`includeMessage=never`. Setting the live key alone would expose every
exception's text: a 5xx's (SQL, file paths), a reason-less 4xx's (the
handler's signature, a JSON parse error) and a validation error's own
message.

**Fix**:
- `application-common.properties` sets
`spring.web.error.include-message=always`.
- `io.meeds.spring.web.error.PortalErrorAttributes` is a `@Component`,
so every WAR that scans `AvailableIntegration.WEB_MODULE` gets it. It
keeps `message` only for a 4xx with an explicit reason (a non-empty
`jakarta.servlet.error.message`) and sets it to that reason. Every other
message is removed: a 5xx's, a reason-less 4xx's, and one with no status
attribute.
- `PortalErrorAttributesTest` boots the servlet error page on an
embedded Tomcat with the real `application-common.properties`. It pins
each case: a 4xx reason, a reason-less 400, a 500, a 503 with a reason,
a validation error, a missing status, and a message that was not
requested. Each guard is mutation-verified, except the `>= 400` bound,
which no handler reaches.
- The embedded Tomcat sets `catalina.home` and `catalina.base` JVM-wide,
and the Kernel then resolves its configuration under them. The test
therefore saves both properties and restores them for the module's
Kernel tests.

**Upgrade impact**
- **Against Spring Boot 3** (`stable/7.2.x-exo`, `stable/25.x-exo`,
where the old key bound):
- A 5xx body no longer carries `message`, including the 5xx
`ResponseStatusException` reasons in email-connector, matrix,
deeds-tenant, ai, content, gamification-crowdin and social.
- A 4xx raised without a reason no longer carries the exception's text.
- A validation error carries Spring's reason ("Invalid request
content.") instead of "Validation failed for …".
  - A 4xx with a reason is unchanged.
- **Against `develop` since the Spring Boot 4.1 upgrade**: a 4xx reason
reaches `$.message` again.
- **Known limit**: a 4xx reason reaches the client as given. That
includes `ResponseStatusException(4xx, e.getMessage())` call sites whose
exception text is prose; `backend-spring` §5 applies at those call
sites.
- **A WAR that imports `application-common.properties`** must scan
`AvailableIntegration.WEB_MODULE`, or its error bodies carry the
exception's text. Every product WAR does; a customer extension must too.
- **mcp-server and documents-webdav** import neither the file nor the
package, so they keep Spring Boot's default (`never`).
- **A `server.error.*` key set by an extension** binds to nothing on
Spring Boot 4. The live group is `spring.web.error.*`.

**Companion PRs** (same task):
- Meeds-io/task#668, Meeds-io/pwa#110, exoplatform/documents#2099,
Meeds-io/deeds-tenant#141: dead key removed, no merge-order constraint.
- exoplatform/agenda#1212, exoplatform/email-connector#576: comments
only, merge after this PR.

Knowledge: Meeds-io/eng-standards#379

This change is classified N1 (Architects Lead, 2026-10-09; computed on
the delivery head `3929728fac`): its approver must be an Archi/Dev who
knows it is N1, not an approval on AI review alone, and author ≠
approver.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@boubaker
boubaker requested a review from Jihed525 October 12, 2026 11:27
@boubaker
boubaker merged commit fe8574f into develop Oct 12, 2026
13 checks passed
@boubaker
boubaker deleted the fix/EXO-91152-error-message branch October 12, 2026 11:37

@ahamdi ahamdi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review — Round #1 (final)

No findings.

Verified conform

  • The removed key was dead: on Spring Boot 4 the server.error.* group binds to nothing (its configuration metadata marks it deprecated at level error since 4.0.0, replaced by spring.web.error.*). Removing it changes nothing at runtime.
  • TaskApplication imports application-common.properties (@PropertySource, TaskApplication.java:44), so the live spring.web.error.include-message=always that Meeds-io/portal#1336 adds there reaches this WAR.
  • It also scans AvailableIntegration.WEB_MODULE (TaskApplication.java:34). portal#1336's comment says every WAR importing that file must scan it, so that PortalErrorAttributes drops the exception text from the error body. Task satisfies that requirement.
  • No merge-order constraint: before portal#1336 lands, the message is not included either way, and after it lands this file no longer carries a conflicting key. No other server.error.* key is left in the repo.
  • Knowledge: Meeds-io/eng-standards#379 is open and in draft, as expected while the code is not on develop. It carries this delivery's update: the pitfall that listed task.properties among the dead keys is replaced by one stating "Never set a server.error.* key".
  • Title, body (Symptom / Cause / Fix) and the EXO-91152 reference follow pr-conventions.md §3.

The PR does one thing only. Its body explains why the deletion is safe and why it does not depend on the portal PR's merge order.

Classification: N1 (Architects Lead, 2026-10-09, for the EXO-91152 delivery, restated as is). An Architect or Developer who knows it is N1 must validate this PR; it must not be auto-merged on the AI review alone.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

partialCIBuild Perform Partial CI Build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants