Troubleshooting
The app says the sample catalog could not be found
Build and run from the repo root, or use the normal dotnet run --project
command shown in Getting Started. The app looks for the
copied sample catalog in its output folder first, then falls back to the repo
copy under samples/quest-session-kit/.
The app launches but cannot find adb
The app now prefers the managed official Quest tooling cache first, then falls
back to normal Android SDK locations. It looks for adb.exe in:
%VISCEREALITY_ADB_EXE%- the current operator-data root under
...\ViscerealityCompanion\tooling\platform-tools\current\platform-tools\adb.exe %LOCALAPPDATA%\Android\Sdk\platform-tools\adb.exe%ANDROID_SDK_ROOT%\platform-tools\adb.exe%ANDROID_HOME%\platform-tools\adb.exe- every entry on
PATH
If you want the repo to install and update the official Meta/Google tooling for you, rerun the guided setup helper or run:
dotnet run --project src/ViscerealityCompanion.Cli -- tooling install-official
If this machine is using the Unity-bundled adb.exe, add that folder to
PATH or install the normal platform-tools package.
The Companion Updates window still shows Installed: n/a after I refreshed the official Quest tools
If the same dialog also says something like:
Official Quest tooling updated
hzdb 1.0.1 | Android platform-tools 37.0.0
then the install itself probably succeeded and the dialog was only still showing its original pre-install snapshot.
That older packaged-window bug affected the per-tool status cards, not the actual managed tooling cache. The real files and metadata live under the current operator-data root:
...\ViscerealityCompanion\tooling\hzdb\current\metadata.json
...\ViscerealityCompanion\tooling\platform-tools\current\metadata.json
Current builds refresh those cards immediately after the in-app tooling update completes. If you are validating an older build, confirm the real state with:
dotnet run --project src/ViscerealityCompanion.Cli -- tooling status
or, from the packaged local-agent workspace:
.\viscereality.ps1 tooling status
If Wi-Fi ADB only works after manual adb kill-server / adb start-server
recovery in cmd, update to the latest packaged release first. The Sussex
Wi-Fi bootstrap now restarts the local ADB server automatically and falls back
to parsing adb shell ip route when getprop dhcp.wlan0.ipaddress does not
return a usable headset IP.
The app launches but hzdb-dependent actions stay unavailable
Quest screenshot capture, Quest file pullback, and the experiment-shell
proximity helper depend on hzdb. The app looks for hzdb in:
%VISCEREALITY_HZDB_EXE%- the current operator-data root under
...\ViscerealityCompanion\tooling\hzdb\current\hzdb.exe %LOCALAPPDATA%\Microsoft\WinGet\Links\hzdb.exe- every entry on
PATH npx.cmdas a legacy fallback
The preferred public path is the managed LocalAppData cache, not npx.
Refresh it with the guided setup helper or:
dotnet run --project src/ViscerealityCompanion.Cli -- tooling install-official
The guided setup helper finished but the app did not open
Current helper builds now try to launch the packaged app automatically through
its Windows AppsFolder target after the MSIX install finishes. If that still
does not bring the app forward on a given machine, treat it as a Windows shell
activation problem, not as proof that the install failed.
Use the normal fallback:
- Open
Viscereality Companionfrom the Start menu. - If both
Viscereality CompanionandViscereality Companion Previewexist, useViscereality Companion. The preview entry is legacy migration state only. - If you want to verify the installed build explicitly, check
Get-AppxPackage MesmerPrism.ViscerealityCompanion*in PowerShell. - If the app opens and the operator-data root contains the managed tooling metadata shown above, the packaged install succeeded.
The app launches but live LSL features stay unavailable
The packaged release and portable Windows zip now bundle the official Windows
x64 lsl.dll. On those builds, live LSL features should work without a
separate liblsl install.
The exported local agent workspace now mirrors that bundled liblsl copy beside
the bundled CLI and sets VISCEREALITY_LSL_DLL in viscereality.ps1 /
viscereality.cmd automatically. If an installed-app local agent still reports
that LSL is missing, do not rely on tooling status alone because that command
only reports the managed hzdb plus Android platform-tools cache.
Use these instead:
.\viscereality.ps1 windows-env analyze
.\viscereality.ps1 study probe-connection sussex-university
When the headset is unavailable or should not be touched, keep the check Windows-only:
.\viscereality.ps1 windows-env analyze --local-only --skip-stream-probe --check-timeout-seconds 5
Maintainers can also run the installed-package smoke check from the repo. It checks the public MSIX install, the exported packaged CLI, the bundled Sussex conditions, and an isolated condition create/update/export/import round trip without launching or stopping anything on the headset:
powershell -ExecutionPolicy Bypass -File .\tools\app\Test-ConsumerInstall.ps1
If LSL still stays unavailable, confirm lsl.dll is reachable through one of
the expected locations:
%VISCEREALITY_LSL_DLL%- next to the app executable
runtimes/win-x64/native/lsl.dll
If the bundled DLL is missing or blocked, the app falls back to degraded availability messaging for those features.
Switching between the TEST sender and another LSL sender is unreliable
Treat that as a Windows-side LSL inventory problem first, not as proof that the headset-side Sussex inlet is broken.
Start with these checks in order:
- Open the Sussex
Windows environmentpage and runRefresh Machine LSL State. - On the same page, run
Analyze Windows Environment. - If the headset path itself is under suspicion, run
Probe Connectionfrom Step 9 in the sequential guide orstudy probe-connection sussex-universityfrom the CLI.
If you need to send the full state to a maintainer, press Generate Diagnostics Report on the same Windows environment page or run:
.\viscereality.ps1 study diagnostics-report sussex-university --wait-seconds 15
Share the generated report folder, especially sussex_lsl_twin_diagnostics.pdf
and sussex_lsl_twin_diagnostics.json. That report captures the Windows LSL
checks, duplicate stream inventory, Quest APK/profile state, quest_twin_state
publisher visibility, return-path interpretation, and a safe twin command
acknowledgement probe without relying on cropped screenshots.
Machine LSL State is the companion-side view. It compares what the app
believes it owns locally against what Windows currently resolves over liblsl.
The most common failure mode is more than one visible
HRV_Biofeedback / HRV publisher on the same machine. That can happen if:
- the companion TEST sender is still advertising after a failed stop
- another companion instance is still open
- an external Python sender is publishing the same stream contract
Current builds now wait for the local TEST sender loop to unwind on stop and warn when the Windows inventory still shows stale companion-owned streams or multiple matching upstream publishers.
The two probes deliberately cover different halves of the fault tree:
Analyze Windows Environmentchecks the local Windows machine: liblsl load path, active IPv4 adapters, VPN or virtual adapter hazards, multicast support, local liblsl discovery health, twin bridge availability, install/launcher footprint leftovers, and whetherHRV_Biofeedback / HRVis visible to this PC. The same pass now warns about multiple packaged Viscereality families, legacy preview leftovers, stale genericviscereality.exeexports in active operator-data roots, and unexpected Viscereality shortcut files that can make Windows Search or App Installer triage confusing. When a live headset selector is available, it also checks the raw PC↔Quest Wi-Fi path: selector drift, host/Quest subnet shape, ICMP reachability, and TCP5555reachability.Probe Connectionchecks the headset path: the installed Sussex APK hash against the pinned release, the required Quest device profile, the current foreground/snapshot Wi-Fi context, the Sussex inlet reported by the runtime, whether freshquest_twin_state / quest.twin.stateframes are returning to Windows, and whether Windows can even see the Quest-owned twin-state outlet plus itssource_id.
That split is important. A Quest can visibly consume the TEST sender while
Windows-side stream discovery fails with a socket/adapter set_option error,
or while the Quest-to-Windows quest_twin_state return path is missing. In the
first case, reduce Windows adapter variables first: disable unused VPN or
virtual adapters, keep the active Wi-Fi network Private, allow the packaged app
through Windows Firewall on Private networks, and confirm the router is not
using client isolation. In the second case, keep Sussex visibly foregrounded and
debug the return telemetry before trusting calibration, recording confirmation,
or routed coherence readback in the GUI.
If the new Quest Wi-Fi transport path row fails while the SSIDs still match,
that is the clearest router diagnosis the shell can currently give. In that
state, stop blaming liblsl or the Sussex APK first; move both devices to a
different router/AP, disable guest/client isolation, or use a lab Wi-Fi that
permits direct client-to-client traffic.
For the return-path case, read the Twin-state outlet line in Probe Connection or viscereality study probe-connection ... --json:
No Quest twin-state outlet is visible on Windowsmeans the forwardHRV_Biofeedback / HRVpath may still be working, but the Quest-originated LSL publisher is not being discovered by Windows. Check router client isolation, Quest foreground/awake state, and whether the Sussex scene has fully started its twin-state outlet.Quest twin-state outlet is visible, but not from the expected Sussex source_idmeans Windows can see a Quest publisher, but the companion's strict bridge will ignore it because it does not match the pinned package/source-id contract. Reinstall the pinned APK and capture the JSON output for the exact observed source id.A twin-state stream is visible, but it does not match the Quest source-id contractusually points at an older or hand-built runtime still advertising a legacy source id such asquest.twin.state.
That duplicate-source warning is advisory for the Windows-side inventory. The
Experiment Session coherence card follows the Quest-reported routed value from
quest_twin_state, including the newer study.lsl.latest_default_value /
study.lsl.latest_ch0_value fields when the direct signal01.coherence_lsl
mirror is absent. If the Quest is processing an external Python sender but the
Windows environment page warns about two publishers, stop the extra publisher
or stale TEST sender to make future stream resolution deterministic; do not
interpret the warning by itself as proof that Sussex stopped consuming the LSL
inlet.
During participant recordings, upstream_lsl_monitor.csv now includes the
resolved LSL source_id for the passive Windows-side inlet. Use that column to
confirm which publisher Windows latched onto when duplicate
HRV_Biofeedback / HRV sources were visible.
Current builds also split Analyze Windows Environment into more precise LSL
hazard checks:
Windows network adapter hazardslists active IPv4 adapters and warns when VPN, Tailscale, WireGuard, Hyper-V, Docker, WSL, TAP/Wintun, VirtualBox, VMware, multiple default gateways, or adapters without multicast support are visible.Windows liblsl discovery self-checkruns a deliberately unique local lookup before checkingHRV_Biofeedback / HRV. If this fails withset_optionorThe requested address is not valid in its context, the Windows LSL inventory is unhealthy even if the Quest still receives samples from a sender.Windows LSL loopback outlet self-checkopens a temporary local LSL outlet and tries to rediscover it from the same process. If the TEST sender says it is active but this loopback check fails, debug Windows LSL advertisement, firewall/profile, and adapter state before debugging the Quest inlet.Expected Sussex LSL streamthen reports whether the actual upstreamHRV_Biofeedback / HRVsource is visible to Windows.
This separation is important for intermittent lab machines. A headset can
consume the TEST sender while the Windows GUI cannot reliably enumerate streams
or receive quest_twin_state. In that case, focus first on Windows network
shape: disable unused VPN/virtual adapters, keep only the lab Wi-Fi/Ethernet
path active if possible, set the active network profile to Private, and allow
the packaged app through Windows Firewall on Private networks.
Stop Recording reports that the operation was canceled
If this happens during Stop Recording or Stop participant recording, first check whether the cancellation occurred during Quest backup pullback rather than during the Windows recording itself.
The stop path is:
- Stop regular Windows recording samples.
- Stop background clock-alignment monitoring.
- Run the end clock-alignment burst.
- Send
End Experiment. - Confirm the Quest recorder stopped.
- Pull Quest backup files into the Windows session folder.
- Write the final stopped marker and complete the local recorder.
Older builds surfaced a timeout or cancellation in step 6 as a generic recorder
fault. Current builds distinguish that case: if hzdb files ls or
hzdb files pull times out while copying the Quest backup, the operator should
see a Quest-backup pullback warning and the Windows session folder path instead
of a misleading whole-recorder failure.
Inspect the reported session folder under the current operator-data root, usually one of:
%LOCALAPPDATA%\ViscerealityCompanion\study-data\...
%LOCALAPPDATA%\Packages\<package-family>\LocalCache\Local\ViscerealityCompanion\study-data\...
Check for:
session_events.csvsignals_long.csvbreathing_trace.csvclock_alignment_roundtrip.csvupstream_lsl_monitor.csvdevice-session-pull\
If the Windows files are present but device-session-pull is absent, empty, or
partial, treat the run as a Quest backup pullback problem. The usual causes are
a slow or dropped Wi-Fi ADB connection, the headset entering an odd foreground
or awake/asleep state, another ADB or hzdb process contending for the device,
or Windows-side IO/security pressure making the hzdb subprocess exceed its
timeout.
Explorer says a Sussex session folder path is not available
Older packaged builds could check a Sussex session folder path from inside the
app and then hand Explorer a non-host-visible alias. Current builds now resolve
the host-visible operator-data root first, so Open Session Folder, Open Quest Backup, Open Session PDF, and the validation-capture folder buttons
should open the real on-disk location.
For packaged installs, that root is usually:
%LOCALAPPDATA%\Packages\<package-family>\LocalCache\Local\ViscerealityCompanion\
For unpackaged/source builds, it remains:
%LOCALAPPDATA%\ViscerealityCompanion\
If you are driving the bundled CLI from the exported agent workspace, use the
generated wrappers (viscereality.ps1, viscereality.cmd, agent-env.ps1,
agent-env.cmd). They now export VISCEREALITY_OPERATOR_DATA_ROOT so the CLI
uses that same host-visible root instead of drifting back to a different bare
LocalAppData path.
The Sussex validation PDF fails even though the Windows session folder exists
This is separate from Quest pullback. The PDF is generated from the Windows
session folder after the run, so it can fail even when Open Windows Session Folder works.
Current public builds render Sussex validation PDFs natively in .NET. They do
not depend on a machine-local Python, numpy, or matplotlib installation.
If PDF generation still fails, the remaining likely causes are:
- the Windows session folder is missing one of the expected recorder artifacts
such as
session_settings.json,signals_long.csv,breathing_trace.csv, orclock_alignment_roundtrip.csv - one of those artifacts exists but is truncated, malformed, or unreadable
- the session folder was moved or deleted before the report renderer finished
The failure detail now comes from the native renderer itself. Treat Quest pullback gaps and PDF generation as separate signals: a Quest backup warning does not automatically mean the Windows-side recorder data was lost.
The packaged launcher path is not available yet
If no signed packaged release exists, use the source-build path from
Getting Started or build an unsigned package locally with
tools/app/Build-App-Package.ps1 -Unsigned.
Smart App Control blocks the guided setup helper
This is usually not evidence that the release asset is unsigned. The current
guided setup helper EXE may still be Authenticode-signed with the repo's
self-issued package certificate. Windows Smart App Control evaluates the
downloaded EXE
before the helper can add that certificate to Trusted People, so fresh
machines can still block the helper outright even though the signature itself is
present and timestamped.
Use this order:
- Install the package certificate from
ViscerealityCompanion.cerintoLocal Machine > Trusted People. - Open the downloaded
ViscerealityCompanion.appinstallerfile from disk. - If App Installer itself still refuses the feed, install the
.msixdirectly.
For release debugging, validate the shipped EXE and MSIX signatures locally:
powershell -ExecutionPolicy Bypass -File .\tools\app\Test-ReleaseAssetSigning.ps1 `
-PreviewSetupPath .\artifacts\windows-installer\ViscerealityCompanion-Setup.exe `
-PackagePath .\artifacts\windows-installer\ViscerealityCompanion.msix `
-AllowSelfSignedPreviewSetup `
-AllowSelfSignedPackage
Current release builds now require an RFC3161 timestamp on both assets. That
improves signature durability, but it does not make the helper Smart App
Control-compliant on fresh machines by itself. To make the helper broadly
trusted under Smart App Control, the release workflow must sign the helper with
a certificate from a trusted public provider or move that helper-signing path
to Microsoft's Trusted Signing flow. The workflow supports a separate guided
setup signing certificate via the existing
WINDOWS_PREVIEW_SETUP_CERTIFICATE_BASE64 and
WINDOWS_PREVIEW_SETUP_CERTIFICATE_PASSWORD secrets so the helper can use a
public Authenticode signer without changing the self-signed MSIX sideloading
path. If that dedicated signer is absent, the workflow now signs the freshly
built helper with the package certificate instead of reusing an old pinned
bootstrapper asset.
If the packaged app itself is blocked after the MSIX installs, inspect the Code Integrity log for the specific package family and executable path:
Get-WinEvent -LogName 'Microsoft-Windows-CodeIntegrity/Operational' -MaxEvents 100 |
Where-Object { $_.Message -match 'MesmerPrism\\.ViscerealityCompanion|ViscerealityCompanion\\.exe' }
The release MSIX must preserve the normal WAP multi-file payload inside
ViscerealityCompanion.App. Do not replace that payload with a repacked
single-file desktop publish, and for this repo do not repack the finished WAP
layout just to inject Authenticode signatures into the inner desktop payload
files. Local validation on this machine family showed that the native
WAP-produced package still launched cleanly, while the manually repacked
payload variant installed successfully but then tripped Code Integrity on
ViscerealityCompanion.exe. Current release validation checks that the package
still contains both ViscerealityCompanion.App/ViscerealityCompanion.exe and
ViscerealityCompanion.App/ViscerealityCompanion.dll.
The repo-local pinned launcher opens an error instead of the app
Refresh the verified single-file launcher path instead of trusting an older repo-local executable or shortcut:
powershell -ExecutionPolicy Bypass -File .\tools\app\Start-Desktop-App.ps1 -Refresh
If you only need to rebuild the Desktop and Start Menu shortcuts, run:
powershell -ExecutionPolicy Bypass -File .\tools\app\Refresh-Desktop-Launcher.ps1
That republish path refreshes the canonical shortcut target and removes stale
repo-local ViscerealityCompanion.exe copies so Windows search and taskbar
pins keep resolving to the right app. If the packaged MSIX release is installed,
the canonical Viscereality Companion.lnk shortcut now tries the packaged app
first and falls back to the repo-local published build when Windows refuses to
start the packaged process.
The docs site does not build
Confirm Node.js is installed, then run:
npm ci
npm run pages:build
The Quest app launches but the monitor or twin view stays empty
Check the study build first:
quest_monitoronly appears if the APK publishes the lightweight monitor outlet- twin-state only appears if the APK publishes
quest_twin_state - the app can still install, launch, and track foreground state over ADB even when those streams are absent
I need to change the Quest runtime itself
Do that in the participant-facing Quest runtime, not here. This repo is the public Windows app and onboarding surface around that runtime.