HTML Push Analytics Job Fails in v2.41.8.1 (400 Bad Request / Invalid dashboard UID "undefined"

Hi Community,

We are facing an issue with the new native HTML Push Analytics job type in DHIS2 version 2.41.8.1.

The job successfully finds our receiver group but completely aborts during execution because the background Java process sends an "undefined" value to our port 3000 rendering service.

What we have configured and tested so far:

  • We configured an HTML Push Analytics scheduler task using a valid dashboard instance (“Test 2” / UID: oeV3cN7zszB) and mapped it to our target receiver user group.
  • We verified the database backend; the job configuration row is properly created with the explicit dashboard UID and receiver parameters.
  • The target dashboard has been fully opened up with sharing settings granted to the target user group to ensure there are no authorization blocks during execution.
  • When we manually query the rendering service on port 3000 using standard query parameters via curl (?dashboardId=oeV3cN7zszB&username=admin), it functions flawlessly and outputs our layout.

However, during the automated scheduler thread run, DHIS2 fails to map or stringify the query variables properly, passing undefined to the rendering service instead.

Please see the attached log file for the complete stack trace details. Any insights would be highly appreciated!

Thanks!

Full Log Stack Trace

* INFO  2026-05-21T21:50:40,090 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] Process started: HTML push analytics (RecordingJobProgress.java [pool-5-thread-1]) UID:H0VvWYcfgpv 
* INFO  2026-05-21T21:50:40,092 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] : Computing receiving users (RecordingJobProgress.java [pool-5-thread-1]) UID:H0VvWYcfgpv 
* INFO  2026-05-21T21:50:40,096 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] completed after 0.005s: Found 1 receivers (RecordingJobProgress.java [pool-5-thread-1]) UID:H0VvWYcfgpv 
* INFO  2026-05-21T21:50:40,097 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] : Validating configuration (RecordingJobProgress.java [pool-5-thread-1]) UID:H0VvWYcfgpv 
* INFO  2026-05-21T21:50:40,098 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] completed after 0.001s (RecordingJobProgress.java [pool-5-thread-1]) UID:H0VvWYcfgpv 
* INFO  2026-05-21T21:50:40,099 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] : Sending push analytics to 1 receivers as viewed by themselves (RecordingJobProgress.java [pool-5-thread-1]) UID:H0VvWYcfgpv 
* WARN  2026-05-21T21:50:40,109 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] Process aborted after 0.019s: aborted after error: 400 Bad Request: "REQUEST HANDLER ERROR (E1502): Invalid dashhboard UID "undefined"" (RecordingJobProgress.java [ForkJoinPool-2-worker-1])  
* ERROR 2026-05-21T21:50:40,109 400 Bad Request: "REQUEST HANDLER ERROR (E1502): Invalid dashhboard UID "undefined"" (DefaultNotifier.java [pool-4-thread-1])  
* ERROR 2026-05-21T21:50:40,109 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] failed after 0.009s: 400 Bad Request: "REQUEST HANDLER ERROR (E1502): Invalid dashhboard UID "undefined"" (RecordingJobProgress.java [ForkJoinPool-2-worker-1])  
org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: "REQUEST HANDLER ERROR (E1502): Invalid dashhboard UID "undefined""
	at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:101)
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:168)
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:122)
	at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
	at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:825)
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:783)
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:717)
	at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:608)
	at org.hisp.dhis.pushanalysis.scheduling.HtmlPushAnalyticsJob.getPushAnalyticsHtmlBody(HtmlPushAnalyticsJob.java:197)
	at org.hisp.dhis.pushanalysis.scheduling.HtmlPushAnalyticsJob.lambda$execute$3(HtmlPushAnalyticsJob.java:131)
	at org.hisp.dhis.scheduling.JobProgress.runStage(JobProgress.java:481)
	at org.hisp.dhis.scheduling.JobProgress.runStage(JobProgress.java:463)
	at org.hisp.dhis.scheduling.JobProgress.runStage(JobProgress.java:456)
	at org.hisp.dhis.pushanalysis.scheduling.HtmlPushAnalyticsJob.lambda$execute$4(HtmlPushAnalyticsJob.java:131)
	at org.hisp.dhis.scheduling.JobProgress.lambda$runStageInParallel$5(JobProgress.java:527)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1850)
	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$ReduceTask.doLeaf(ReduceOps.java:960)
	at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:934)
	at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327)
	at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:754)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:686)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:927)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
	at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:662)
	at org.hisp.dhis.scheduling.JobProgress.lambda$runStageInParallel$6(JobProgress.java:537)
	at java.base/java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1428)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
* ERROR 2026-05-21T21:50:40,121 Error while sending email: Invalid message., org.apache.commons.mail.EmailException: Invalid message.
	at org.apache.commons.mail.EmailException.check(EmailException.java:54)
	at org.apache.commons.mail.EmailException.checkNonEmpty(EmailException.java:64)
	at org.apache.commons.mail.HtmlEmail.setTextMsg(HtmlEmail.java:577)
	at org.hisp.dhis.message.EmailMessageSender.sendMessage(EmailMessageSender.java:218)
	at org.hisp.dhis.message.EmailMessageSender$$FastClassBySpringCGLIB$$d8bb5f81.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy.invokeMethod(CglibAopProxy.java:386)
	at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:85)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703)
	at org.hisp.dhis.message.EmailMessageSender$$EnhancerBySpringCGLIB$$f8388b8c.sendMessage(<generated>)
	at org.hisp.dhis.message.EmailMessageSender$$FastClassBySpringCGLIB$$d8bb5f81.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137)
	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:707)
	at org.hisp.dhis.message.EmailMessageSender$$EnhancerBySpringCGLIB$$d99a8215.sendMessage(<generated>)
	at org.hisp.dhis.email.DefaultEmailService.sendEmail(DefaultEmailService.java:82)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241)
	at jdk.proxy3/jdk.proxy3.$Proxy444.sendEmail(Unknown Source)
	at org.hisp.dhis.pushanalysis.scheduling.HtmlPushAnalyticsJob.lambda$execute$4(HtmlPushAnalyticsJob.java:132)
	at org.hisp.dhis.scheduling.JobProgress.lambda$runStageInParallel$5(JobProgress.java:527)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1850)
	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$ReduceTask.doLeaf(ReduceOps.java:960)
	at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:934)
	at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327)
	at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:754)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:686)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:927)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
	at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:662)
	at org.hisp.dhis.scheduling.JobProgress.lambda$runStageInParallel$6(JobProgress.java:537)
	at java.base/java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1428)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
 (EmailMessageSender.java [ForkJoinPool-2-worker-1])  
* INFO  2026-05-21T21:50:40,122 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] completed after 0s (RecordingJobProgress.java [pool-5-thread-1]) UID:H0VvWYcfgpv 
* INFO  2026-05-21T21:50:40,123 [HTML_PUSH_ANALYTICS H0VvWYcfgpv] Process completed after 0.001s (RecordingJobProgress.java [pool-5-thread-1]) UID:H0VvWYcfgpv 
* ERROR 2026-05-21T21:50:40,130 Job failed: 'HTML Push Analysis Job' (DefaultJobSchedulerLoopService.java [pool-5-thread-1]) UID:H0VvWYcfgpv 

Hi

Sorry to see that you’re facing this unexpected issue. Could you share the configuration settings of the job, /api/jobConfigurations/H0VvWYcfgpv?

Could you also try using the Data Administration app > Maintenance (clear application cache, reload apps)?

And if you’re willing to experiment a little, what happens if you try to ‘duplicate the dashboard’ and recreated the job?

Sorry for not giving you a direct answer, looks like it needs a little investigation. Thanks!

Hi @Pomi_Daniel,

I have tried to troubleshoot and debug a bit with our AI assistants to figure out what is causing the issue. Thanks for all the information, that is very helpful!

Could you check two things so we can confirm further what the issue is?

  1. The value of the setting: GET /api/systemSettings/keyHtmlPushAnalyticsUrl
  2. Alternatively, temporarily switch the job to EXECUTOR mode and run it again, since in that mode the job logs the full substituted URL, so you’ll see exactly what’s being sent (in RECEIVER mode that URL isn’t logged, which is why your log doesn’t show it).

I’ll also raise a JIRA to make the error message clearer in core so it’s easier to diagnose in the future - and possibly a JIRA issue for the Scheduler app depending on what the issue turns out to be.

Thanks!
Karoline
DHIS2 Product Manager