From meta-vr
Debugs Meta Quest and Horizon OS VR/MR apps using hzdb CLI: view logs, capture screenshots, diagnose crashes, errors, and issues on connected devices.
npx claudepluginhub meta-quest/agentic-tools --plugin meta-vrThis skill is limited to using the following tools:
Debug Meta Quest VR and MR applications using the `hzdb` command-line interface. This skill covers viewing application logs, capturing device state, diagnosing crashes, and resolving common issues encountered during Quest development.
Verifies Meta Quest VR facts and APIs against official docs via hzdb tools before answering questions or writing code for Quest headsets and apps. Auto-activates in Quest projects.
Sets up OpenXR for VR/AR/XR apps in Godot 4.3+: XROrigin3D, controllers, hand tracking, passthrough, input handling, Meta Quest deployment.
Builds immersive VR/AR experiences using WebXR, Three.js XR, Quest/Meta development, hand tracking, spatial UI/UX, AR anchors, and XR performance optimization. Useful for VR/AR/WebXR projects.
Share bugs, ideas, or general feedback.
Debug Meta Quest VR and MR applications using the hzdb command-line interface. This skill covers viewing application logs, capturing device state, diagnosing crashes, and resolving common issues encountered during Quest development.
Use this skill when you need to:
This skill is relevant for any Meta Quest headset (Quest 2, Quest 3, Quest 3S, Quest Pro) running Horizon OS.
Before using this skill, ensure the following are in place:
npx -- The hzdb CLI is invoked on demand; no global install required:
npx -y @meta-quest/hzdb --version
hzdb wraps ADB and adds Quest-specific device management, log viewing, screenshot capture, and file management. Examples below use the bare hzdb command for brevity — substitute npx -y @meta-quest/hzdb in front.The fastest way to begin debugging a Quest application:
# 1. Verify the device is connected and recognized
hzdb device list
# 2. List applications currently installed
hzdb app list
# 3. View live logs (most recent 100 lines)
hzdb log
# 4. Capture a screenshot of the current VR view
hzdb capture screenshot
If hzdb device list returns no devices, check the USB cable, developer mode, and ADB authorization.
| Command | Description |
|---|---|
hzdb device list | List all connected Quest devices |
hzdb device info <id> | Show device model, OS version, and more |
hzdb device battery | Show battery level and charging status |
hzdb device wake | Wake the device from sleep |
hzdb device reboot | Reboot the device |
hzdb device connect <ip> | Connect to a device over WiFi |
| Command | Description |
|---|---|
hzdb log | View the last 100 log lines |
hzdb log -n 500 | View the last 500 log lines |
hzdb log --tag Unity | Filter logs by tag |
hzdb log --level E | Filter by severity (V, D, I, W, E, F) |
hzdb adb logcat | Full logcat with advanced filtering options |
hzdb adb logcat --follow | Stream logs continuously |
| Command | Description |
|---|---|
hzdb app list | List installed applications |
hzdb app info <package> | Show detailed info about an app |
hzdb app launch <package> | Launch an application by package name |
hzdb app stop <package> | Force-stop a running application |
hzdb app clear <package> | Clear application data and cache |
hzdb app install <apk> | Install an APK to the device |
hzdb app uninstall <package> | Uninstall an application |
| Command | Description |
|---|---|
hzdb capture screenshot | Capture a screenshot of the current VR/MR view |
hzdb capture screenshot -o file.png | Save screenshot to a specific file |
| Command | Description |
|---|---|
hzdb files ls /sdcard/ | List files on the device |
hzdb files pull /sdcard/path/file ./local/ | Pull a file from the device |
hzdb files push ./local/file /sdcard/path/ | Push a file to the device |
hzdb files rm /sdcard/path/file | Delete a file on the device |
hzdb files mkdir /sdcard/path/dir | Create a directory on the device |
A typical debugging session follows this pattern:
hzdb device list
hzdb device info <device_id>
Confirm the device is recognized, check the OS version, and note the battery level. A low battery can cause thermal throttling that affects performance tests.
hzdb app list
Find the package name for the application you want to debug. Package names typically follow the pattern com.company.appname.
# Start logging before reproducing the issue
hzdb adb logcat --follow
Put on the headset and reproduce the issue. The logs stream in real time to your terminal. Press Ctrl+C to stop.
# Take a screenshot at the moment of the issue
hzdb capture screenshot
Review the captured logs for errors, warnings, and crash signatures. Look for:
FATAL EXCEPTION -- Unhandled Java/Kotlin exceptionsnative crash or SIGABRT / SIGSEGV -- Native code crashesANR -- Application Not Responding (frozen UI thread)OOM or OutOfMemoryError -- Memory exhaustionMake code changes, rebuild, deploy, and test again:
hzdb app stop com.example.myapp
hzdb app launch com.example.myapp
hzdb log --tag Unity --level W
When a developer reports a problem, use these decision trees to systematically diagnose the root cause. Start with the reported symptom and follow the branches.
App crashes on launch
├── Does `hzdb app launch <pkg>` show "Error: Activity not found"?
│ └── YES → Package name is wrong or app is not installed.
│ Run `hzdb app list` to verify the correct package name.
├── Does logcat show `FATAL EXCEPTION` in the first 5 seconds?
│ ├── YES, with `ClassNotFoundException` or `NoClassDefFoundError`
│ │ └── Missing native library or wrong ABI. Check the APK is built for ARM64.
│ │ Run: `hzdb adb shell getprop ro.product.cpu.abi` → must show "arm64-v8a"
│ ├── YES, with `SecurityException` or `Permission denied`
│ │ └── Missing manifest permission. Check the logcat message for which permission.
│ │ Common: hand tracking, scene, camera permissions not declared.
│ └── YES, with `NullPointerException` or other Java exception
│ └── Application code bug. Read the stack trace for the failing class and method.
├── Does logcat show `native crash` / `SIGSEGV` / `SIGABRT`?
│ ├── Check if the crash is in a Unity/Unreal library (libunity.so, libUE4.so)
│ │ └── Engine bug or incompatible SDK version. Check Meta XR SDK release notes
│ │ for known issues with your engine version.
│ └── Check if the crash is in your own native code
│ └── Debug with `hzdb adb logcat --buffer crash` for the tombstone, then use
│ `addr2line` or `ndk-stack` on the crash address.
└── No crash visible in logs?
└── Check if the app is being killed by the system.
Run: `hzdb adb logcat --tag ActivityManager --level W`
Look for "Force stopping" or "Process died" messages. Common cause: OOM killer
triggered by excessive memory usage on launch.
App freezes or ANR dialog appears
├── Does logcat show "ANR in <package>"?
│ ├── YES, with "Reason: Input dispatching timed out"
│ │ └── The main/UI thread is blocked. Check for:
│ │ - Synchronous network calls on the main thread
│ │ - Large file I/O on the main thread
│ │ - Deadlocks between threads
│ │ Run: `hzdb adb shell kill -3 <pid>` to dump thread stacks, then
│ │ `hzdb files pull /data/anr/traces.txt ./` to retrieve the ANR trace.
│ └── YES, with "Reason: executing service"
│ └── A background service is taking too long. Check the service implementation.
└── No ANR, but app appears frozen?
├── Is the render loop still running? (Check VrApi logs for frame submission)
│ ├── YES → The app is rendering but not processing input. Check input system.
│ └── NO → The render thread is blocked or crashed silently.
│ Check: `hzdb adb logcat --tag VrApi` for "FPS" lines stopping.
└── Is the device overheating?
Run: `hzdb device battery` — if battery temperature > 40°C, thermal
throttling may have halted the app. Let device cool down and retry.
Black screen after app launch
├── Is the app actually running?
│ Run: `hzdb adb shell pidof <package>` — if empty, app crashed silently.
│ └── Check crash logs: `hzdb adb logcat --buffer crash`
├── Is VrApi initialized?
│ Check: `hzdb adb logcat --tag VrApi | grep "VrApi" | head -20`
│ ├── No VrApi output → XR session never started. Check OpenXR/OVR initialization code.
│ └── VrApi output exists → Frames are being submitted but may be empty.
│ └── Check: rendering pipeline, camera setup, shader compilation errors.
├── Unity-specific: "Shader compiler" or "Compiling shaders" in logs?
│ └── Shader warmup can cause a black screen for several seconds on first launch.
│ Use shader prewarming/variant preloading to avoid this.
└── Is the correct rendering API being used?
Check: `hzdb adb logcat --tag Unity --level E` for Vulkan/GLES errors.
Quest requires OpenGL ES 3.0 minimum. Vulkan is preferred on Quest 3.
App stutters or drops frames
├── Check current FPS:
│ `hzdb adb logcat --tag VrApi | grep FPS`
│ ├── FPS consistently below 72 → GPU or CPU bottleneck.
│ │ ├── Check GPU: use Perfetto or OVR Metrics Tool. Look for GPU completion
│ │ │ time > 13.8ms (72Hz) or > 11.1ms (90Hz).
│ │ └── Check CPU: look for game thread or render thread exceeding frame budget.
│ └── FPS mostly stable but periodic drops
│ ├── Check for GC pauses: `hzdb adb logcat --tag dalvikvm --level D`
│ │ or `hzdb adb logcat --regex "GC_|clamp"` → reduce allocations per frame.
│ ├── Check for thermal throttling: `hzdb adb logcat --tag ThermalService --level W`
│ │ → sustained heavy load causes CPU/GPU frequency reduction.
│ └── Check for asset loading on main thread: large textures or models loaded
│ synchronously will cause frame spikes. Use async loading.
└── Only stutters in specific scenes?
└── Profile that scene. Common causes: too many draw calls (>100), unculled
off-screen geometry, expensive shaders, excessive overdraw, uncompressed textures.
Controllers or hands not tracking correctly
├── Are controllers paired and connected?
│ `hzdb device info <id>` — check controller connection status.
├── Is hand tracking enabled in device settings?
│ Check: Settings > Movement Tracking > Hand and Body Tracking.
├── Does the app request the correct tracking mode?
│ ├── For hand tracking: manifest must include
│ │ `com.oculus.permission.HAND_TRACKING` and
│ │ `com.oculus.handtracking.frequency` set to "HIGH" if needed.
│ └── For controller tracking: ensure the app is not forcing hand-tracking-only mode.
└── Tracking works but is jittery or delayed?
├── Check lighting: tracking cameras need adequate, even lighting. Very bright
│ or very dim environments degrade tracking quality.
└── Check for occlusion: hands or controllers held outside the tracking camera
FOV will lose tracking. The camera FOV is approximately 110 degrees.
No audio or wrong audio output
├── Is audio playing through the headset speakers?
│ └── Check: Settings > Sound — ensure headset speakers are selected, not Bluetooth.
├── Does the app use spatial audio?
│ ├── Check for FMOD/Wwise initialization errors in logcat.
│ └── Check that audio sources have correct 3D settings and are not muted.
├── Audio is distorted or crackling?
│ └── Audio buffer underruns. Check for CPU overload causing audio thread starvation.
│ Reduce audio complexity or increase buffer size.
└── Audio plays from wrong position?
└── Check spatial audio source positions match visual object positions.
Common issue: audio listener not attached to the camera/head transform.
These are common debugging pitfalls specific to Quest development.
hzdb adb logcat --follow before reproducing.hzdb device list shows nothing, try a different cable before troubleshooting software. The cable that came with the Quest works for data.hzdb device connect <ip>) drop after the device sleeps. You must reconnect after waking the device. USB is more reliable for sustained debugging sessions.android:debuggable="false" (release builds), some log output is suppressed. Debug with a debug build when investigating issues. Do not ship debuggable builds to the store.Unity, il2cpp, and mono depending on the scripting backend. Unreal uses UE, LogVR, and LogOnline. Filter broadly at first, then narrow down.Use severity filters to cut through noise:
# Show only errors
hzdb log --level E
# Show warnings and above
hzdb log --level W
Filter by tag to focus on specific subsystems:
hzdb adb logcat --tag VrApi
hzdb adb logcat --tag Unity
Use advanced filters with hzdb adb logcat:
# Complex filter expressions
hzdb adb logcat --filter "Unity:W ActivityManager:I"
# Regex pattern matching
hzdb adb logcat --regex "error|exception"
# Specific log buffer
hzdb adb logcat --buffer crash
See logcat-filtering.md for a full guide on log filtering techniques.
When investigating crashes, search the log output for known patterns:
hzdb log | grep -i "fatal\|crash\|exception\|anr"
Common crash-related tags include AndroidRuntime, DEBUG, and libc.
Many Horizon OS features require specific manifest permissions. If a feature silently fails, check that the application manifest includes the required permissions. Common ones:
com.oculus.permission.HAND_TRACKING -- Hand tracking accesscom.oculus.permission.USE_SCENE -- Scene API spatial data accessandroid.permission.RECORD_AUDIO -- Microphone accessandroid.permission.CAMERA -- Camera access (for mixed reality)If the application stutters or drops frames:
# Check device battery and thermal state
hzdb device battery
# Watch for thermal throttling messages in logs
hzdb adb logcat --tag ThermalService --level W
# Check VrApi frame timing
hzdb adb logcat --tag VrApi | grep FPS
See common-issues.md for a catalog of known issues and their solutions.