Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Docs: dispatchEvent fails silently with non-POJO data

Open
#131 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
45/100
Issue type
Documentation
Clarity
Mostly clear
Activity status
Stale
Tech stack
typescript

Research direction

Start with the BackgroundRunner.dispatchEvent documentation linked in the issue, especially the details key description. Document that details must be a plain, JSON-serializable object and note the non-POJO failure mode and sanitization workaround; it is done when the warning is clear to users passing plugin results.

Written by the indexing model from the issue text.

Description

Suggested Documentation Improvement

The Problem

Calling await BackgroundRunner.dispatchEvent() can hang indefinitely without throwing an error if the details payload contains a non-plain JavaScript object (POJO). The await never resolves, and the event is never received by the background task, making it very difficult to debug.

This commonly occurs when passing data directly from other Capacitor plugins, such as the GeolocationPosition object from @capacitor/geolocation, which I believe is a class instance, not a plain object. Even though the object looks serializable when logged to the console, it causes the native bridge to fail silently.

A reliable workaround is to sanitize the data before dispatching, for example, by using JSON.parse(JSON.stringify(data)).

How to Reproduce

Set up a listener for an event in the background runner.

In the frontend, get the user's location using @capacitor/geolocation.

Call dispatchEvent and pass the entire position object returned from the geolocation plugin in the details payload.

Observe that the code execution stops at the await and the background task does not log the event.

Code Example
// This code will cause the dispatchEvent call to hang
import { Geolocation } from '@capacitor/geolocation';
import { BackgroundRunner } from 'capacitor-background-runner';

async function dispatchLocationUpdate() {
  // The 'position' object is an instance of GeolocationPosition, not a plain object.
  const position = await Geolocation.getCurrentPosition();

  console.log('Attempting to dispatch event...');
  
  await BackgroundRunner.dispatchEvent({
    label: 'com.example.app.locationUpdate',
    event: 'locationUpdated',
    details: {
      locationData: position // This is the problematic part
    }
  });

  // This line is never reached
  console.log('Event dispatched successfully!');
}

Suggested Solution

It may be worth updating the documentation for BackgroundRunner.dispatchEvent to include a warning or a note about this behavior. The documentation should explicitly state that the details object must be a plain, JSON-serializable object and not a class instance. The type is [key: string]: any at the moment, so maybe some details about this here in the docs under description of the details key?

Image

Quick fix:

For anyone finding this issue, try to JSON.parse(JSON.stringify(details))
This method is easy, available and deep-clones the object, stripping any class information.

const position = await Geolocation.getCurrentPosition();

  console.log('Attempting to dispatch event...');
  
  await BackgroundRunner.dispatchEvent({
    label: 'com.example.app.locationUpdate',
    event: 'locationUpdated',
    details: {
      locationData: JSON.parse(JSON.stringify(position)) // This is the fix
    }
  });

Adding this to the documentation would save developers significant time and confusion. I'd be happy to submit a PR for the documentation change if that would be helpful, and if you could point me in the right direction of the file to change.

My Environment

Capacitor Version: 7.x

capacitor-background-runner Version: ^2.1.0

Platform(s): iOS / Android

Dominant language
C
Stars
57
Forks
37
Avg merge
3d 17h
Merged PRs (30d)
3

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ionic-team/capacitor-background-runner

All issues in ionic-team/capacitor-background-runner

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.