Skip to content

NullPointerException in TransModel API when filtering by sub-mode without main mode #6969

@vpaturet

Description

@vpaturet

In the TransModel API, when filtering the results by transport sub-mode without specifying a tranport mode, the query fails with the following exception:

Exception while fetching data (/trip) : element cannot be mapped to a null key
java.lang.NullPointerException: element cannot be mapped to a null key
	at java.base/java.util.Objects.requireNonNull(Objects.java:259)
	at java.base/java.util.stream.Collectors.lambda$groupingBy$53(Collectors.java:1105)
	at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at org.opentripplanner.model.modes.FilterFactory.create(FilterFactory.java:73)
	at org.opentripplanner.model.modes.AllowTransitModeFilter.of(AllowTransitModeFilter.java:14)
	at org.opentripplanner.routing.api.request.request.filter.SelectRequest.<init>(SelectRequest.java:30)
	at org.opentripplanner.routing.api.request.request.filter.SelectRequest$Builder.build(SelectRequest.java:192)
	at org.opentripplanner.apis.transmodel.mapping.SelectRequestMapper.mapSelectRequest(SelectRequestMapper.java:61)
	at org.opentripplanner.apis.transmodel.mapping.TransitFilterNewWayMapper.mapFilter(TransitFilterNewWayMapper.java:34)
	at org.opentripplanner.apis.transmodel.mapping.TripRequestMapper.lambda$createRequest$10(TripRequestMapper.java:88)
	at org.opentripplanner.routing.api.request.request.TransitRequestBuilder.apply(TransitRequestBuilder.java:84)
	at org.opentripplanner.routing.api.request.request.JourneyRequestBuilder.withTransit(JourneyRequestBuilder.java:35)
	at org.opentripplanner.apis.transmodel.mapping.TripRequestMapper.lambda$createRequest$11(TripRequestMapper.java:74)
	at org.opentripplanner.routing.api.request.request.JourneyRequestBuilder.apply(JourneyRequestBuilder.java:88)
	at org.opentripplanner.routing.api.request.RouteRequestBuilder.withJourney(RouteRequestBuilder.java:72)
	at org.opentripplanner.apis.transmodel.mapping.TripRequestMapper.createRequest(TripRequestMapper.java:71)
	at org.opentripplanner.apis.transmodel.TransmodelGraphQLPlanner.plan(TransmodelGraphQLPlanner.java:38)
	at graphql.execution.ExecutionStrategy.invokeDataFetcher(ExecutionStrategy.java:510)
	at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:464)
	at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:404)
	at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:363)
	at graphql.execution.ExecutionStrategy.getAsyncFieldValueInfo(ExecutionStrategy.java:328)
	at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:57)
	at graphql.execution.Execution.executeOperation(Execution.java:205)
	at graphql.execution.Execution.execute(Execution.java:124)
	at graphql.GraphQL.execute(GraphQL.java:549)
	at graphql.GraphQL.lambda$parseValidateAndExecute$13(GraphQL.java:479)
	at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
	at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2341)
	at graphql.EngineRunningState.compose(EngineRunningState.java:87)
	at graphql.GraphQL.parseValidateAndExecute(GraphQL.java:474)
	at graphql.GraphQL.lambda$executeAsync$9(GraphQL.java:434)
	at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
	at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2341)
	at graphql.EngineRunningState.compose(EngineRunningState.java:87)
	at graphql.GraphQL.lambda$executeAsync$10(GraphQL.java:423)
	at graphql.EngineRunningState.call(EngineRunningState.java:198)
	at graphql.GraphQL.executeAsync(GraphQL.java:416)
	at graphql.GraphQL.execute(GraphQL.java:359)
	at org.opentripplanner.apis.transmodel.TransmodelGraph.executeGraphQL(TransmodelGraph.java:69)
	at org.opentripplanner.apis.transmodel.TransmodelAPI.getGraphQL(TransmodelAPI.java:104)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:146)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:189)
	at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:93)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
	at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:274)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:266)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:253)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:696)
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:367)
	at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:190)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:535)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:515)
	at java.base/java.lang.Thread.run(Thread.java:1583)

Example query:

{
  trip(
    from: {name: "Bjerkealleen 5A, Skedsmo", coordinates: {latitude: 59.96050414081307, longitude: 11.040338686322317}}
    to: {place: "NSR:StopPlace:385", name: "Alna, Oslo"}
    numTripPatterns: 3
    dateTime: "2025-10-14T03:19:10.675+02:00"
    walkSpeed: 1.3
    arriveBy: false
    filters: {not: {transportModes: {transportSubModes: [schoolBus, nightBus]}}}
  ) {
    tripPatterns {
      expectedStartTime
      duration
      walkDistance
      legs {
        mode
        distance
        line {
          id
          publicCode
        }
      }
    }
  }
}

Version of OTP used (exact commit hash or JAR name)

dev-2.x

Data sets in use (links to GTFS and OSM PBF files)

Norwegian data

Metadata

Metadata

Assignees

No one assigned

    Labels

    !BugApply to issues describing a bug and PRs witch fixes it.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions