asLody/VirtualApp · error · RuntimeException

Unable to start receiver

Error message

Unable to start receiver ${data.component}: ${e.toString()}

What it means

This RuntimeException is thrown when a BroadcastReceiver registered in the virtual environment throws inside its onReceive() callback. VClientImpl delivers the broadcast to the plugin receiver and, if onReceive raises an exception, wraps it as 'Unable to start receiver <component>'. The chained cause contains the actual plugin bug.

Solutions

  1. Inspect the `caused by` stack trace to find the real exception inside onReceive
  2. Null-check Intent extras and context state in the plugin receiver's onReceive
  3. Wrap risky work in the receiver with try/catch or move it to a Service/JobScheduler
  4. Verify the receiver's actions/categories match what the sender actually broadcasts

Example fix

// before
public void onReceive(Context c, Intent i) { String id = i.getStringExtra("id").toUpperCase(); }
// after
public void onReceive(Context c, Intent i) { String id = i.getStringExtra("id"); if (id != null) { id = id.toUpperCase(); } }
Defensive patterns

Strategy: try-catch

Try / catch

try { receiver.dispatch(...) } catch (RuntimeException e) { Log.e(TAG, "receiver " + component + " failed: " + e.getCause(), e.getCause()); }

Prevention

When it happens

Trigger: A broadcast is dispatched to a plugin-registered receiver whose onReceive(Context, Intent) throws any Exception; data.component identifies the failing receiver.

Common situations: Plugin receiver assumes an Intent extra exists but it is missing; receiver does network/file I/O that fails; receiver references classes not present in the plugin classloader; system broadcast format changed across Android versions.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of asLody/VirtualApp@666fefcb5d (2026-09-09). Data as JSON: /api/errors/5224595ed4258b44. Report an issue: GitHub.

Appendix: source

Thrown at VirtualApp/lib/src/main/java/com/lody/virtual/client/VClientImpl.java:632

            if (!isBound()) {
                bindApplication(data.component.getPackageName(), data.processName);
            }
            Context context = mInitialApplication.getBaseContext();
            Context receiverContext = ContextImpl.getReceiverRestrictedContext.call(context);
            String className = data.component.getClassName();
            BroadcastReceiver receiver = (BroadcastReceiver) context.getClassLoader().loadClass(className).newInstance();
            mirror.android.content.BroadcastReceiver.setPendingResult.call(receiver, result);
            data.intent.setExtrasClassLoader(context.getClassLoader());
            if (data.intent.getComponent() == null) {
                data.intent.setComponent(data.component);
            }
            receiver.onReceive(receiverContext, data.intent);
            if (mirror.android.content.BroadcastReceiver.getPendingResult.call(receiver) != null) {
                result.finish();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(
                    "Unable to start receiver " + data.component
                            + ": " + e.toString(), e);
        }
        VActivityManager.get().broadcastFinish(data.resultData);
    }

    @Override
    public IBinder createProxyService(ComponentName component, IBinder binder) {
        return ProxyServiceFactory.getProxyService(getCurrentApplication(), component, binder);
    }

    @Override
    public String getDebugInfo() {
        return "process : " + VirtualRuntime.getProcessName() + "\n" +
                "initialPkg : " + VirtualRuntime.getInitialPackageName() + "\n" +
                "vuid : " + vuid;
    }

View on GitHub (pinned to 666fefcb5d)