Skip to content

boundary-service: /boundary/_search NPEs ("argument \"content\" is null") when boundary.additionaldetails is NULL #1389

Description

@singhalkarun

Summary

POST /boundary-service/boundary/_search (the boundary entity search) returns HTTP 400 for any boundary whose additionaldetails column is NULL:

{"ResponseInfo":null,"Errors":[{"id":"IllegalArgumentException","code":"An unhandled exception occurred on the server","message":"argument \"content\" is null"}]}

The boundary relationship search (/boundary-relationships/_search) is unaffected — it doesn't map the entity's jsonb columns.

Root cause

core-services/boundary-service/src/main/java/digit/repository/rowmapper/BoundaryEntityRowMapper.java calls ObjectMapper.readTree(...) directly on the column values:

.geometry(mapper.readTree(resultSet.getString("geometry")))
.additionalDetails(mapper.readTree(resultSet.getString("additionaldetails")))

When additionaldetails (or geometry) is SQL NULL, resultSet.getString(...) returns null, and Jackson's readTree(String) throws IllegalArgumentException: argument "content" is null (from _assertNotNull("content", content)). It is not caught by the surrounding catch (JsonProcessingException e), so it propagates as an unhandled 500/400.

Both jsonb columns are nullable in the schema, and additionaldetails is legitimately null for boundaries created without it.

Impact

Beyond the endpoint itself, egov-hrms employee _create calls /boundary/_search to validate the employee's jurisdiction, so employee onboarding fails for every row when the tenant's boundaries have null additionaldetails — with the same opaque argument "content" is null message surfaced in HRMS, which makes it hard to trace back to boundary-service.

Reproduction

  1. Insert a boundary with additionaldetails = NULL (the default when created without it).
  2. POST /boundary-service/boundary/_search?tenantId=<t>&codes=<code> → 400 argument "content" is null.
  3. Set additionaldetails = '{}'::jsonb on that row → the same call returns 200.

Suggested fix

Null-guard both jsonb columns before readTree:

String geometryJson          = resultSet.getString("geometry");
String additionalDetailsJson = resultSet.getString("additionaldetails");
boundary = Boundary.builder()
        .id(resultSet.getString("id"))
        .code(resultSet.getString("code"))
        .auditDetails(auditDetails)
        .geometry(geometryJson != null ? mapper.readTree(geometryJson) : null)
        .additionalDetails(additionalDetailsJson != null ? mapper.readTree(additionalDetailsJson) : null)
        .tenantId(resultSet.getString("tenantid"))
        .build();

Environment

  • Image: egovio/boundary-service:maven-jdk21-9f83afb
  • Observed on a DIGIT/PGR deployment; confirmed both the failure and that additionaldetails='{}' resolves it, and that a full HRMS employee _create then succeeds end to end.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions