launchApp defaults to REINSTALL (clearState=true) — silently wipes app data & resets permissions, contradicting its "as if a user tapped the icon" description
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
Research direction
Start in trailblaze-common/src/jvmAndAndroid/kotlin/xyz/block/trailblaze/toolcalls/commands/LaunchAppTrailblazeTool.kt, reading the launchMode default, fromString fallback, launch-mode mapping, and LLMDescription. Change the no-argument and unknown-mode behavior to preserve app state, clearly describe REINSTALL as destructive, and verify that explicit REINSTALL still clears state while the default matches RESUME.
Written by the indexing model from the issue text.
Description
Summary
launchApp's default launch mode is REINSTALL, which maps to clearState = true — so calling launchApp appId=<pkg> with no explicit launchMode silently wipes the app's local data (and resets its runtime permissions) before launching. This logs the user out and deletes downloads/offline content/settings.
This directly contradicts the tool's own one-line description — "Open an app on the device as if a user tapped on its icon in the launcher." Tapping a launcher icon never clears app state. The mode that actually matches that description is RESUME, not the current default.
A destructive, state-wiping operation should never be the default for a tool described as "just open the app," especially one driven by an LLM agent that will call it to simply bring an app to the foreground.
What happened (concrete)
During a benign task — opening a series of already-installed, signed-in third-party apps just to read their current screen — each was launched with launchApp appId=<pkg> and no launchMode argument. Every app came up in a fresh, logged-out onboarding state. Root cause: the default REINSTALL cleared each app's data. Several real apps were logged out and their local state (downloads, settings) destroyed before the behavior was noticed. Nothing in the call site or the tool's description hinted that "open the app" would clear it.
Root cause
trailblaze-common/src/jvmAndAndroid/kotlin/xyz/block/trailblaze/toolcalls/commands/LaunchAppTrailblazeTool.kt
- Line 32 — the default:
val launchMode: LaunchMode = LaunchMode.REINSTALL - Lines 71–76 —
REINSTALL -> clearState = true(RESUME and FORCE_RESTART are bothclearState = false) - Line 105 —
fromString(...)also falls back toREINSTALLfor unknown/empty input, so a malformed mode string ALSO wipes state - Lines 18–19 — class
@LLMDescription: "Open an app on the device as if a user tapped on its icon in the launcher." (describes RESUME behavior, not REINSTALL)
clearState = true reaches Maestro's clearAppState(appId), whose own comment notes "Android's clear command also resets permissions" — so the blast radius is data wipe plus permission reset.
Why this is bad
- Least-surprise violation: the default contradicts the documented behavior. "Open the app as if tapping its icon" should be non-destructive.
- Silent + irreversible: no confirmation, no warning; cleared data/logins can't be recovered.
- High blast radius for agents: an autonomous agent calling
launchAppto inspect an app will unexpectedly nuke that app's state. On a real or shared device this means logging people out of streaming/shopping/travel/etc. apps and wiping their downloads and permissions. fromStringfallback compounds it: an unrecognizedlaunchModevalue silently degrades to the most destructive option instead of the safest.
Reproduction
- Install any app and sign in (so it has real local state).
- Run:
trailblaze tool launchApp appId=com.example.app(nolaunchMode). - Observe the app opens logged out / first-run onboarding — its data was cleared.
- Contrast with
launchApp appId=com.example.app launchMode=RESUME, which opens it normally with state intact.
Proposed fix (secret recipe)
Make the non-destructive mode the default, and make the destructive one explicit + clearly labeled. In LaunchAppTrailblazeTool.kt:
- Line 32 — change the default:
val launchMode: LaunchMode = LaunchMode.RESUME, - Line 105 — change the
fromStringfallback so unknown input degrades to safe, not destructive:?: RESUME - Lines 24–31 — update the
@LLMDescriptionso the default is RESUME and REINSTALL is clearly flagged as destructive, e.g.:
And align the class description (lines 18–19) with the fact that the default no longer clears state.- "RESUME" (Default) opens the app as if tapped from the launcher; keeps existing state/login. - "FORCE_RESTART" stops then relaunches the app without clearing state. - "REINSTALL" DESTRUCTIVE: clears all app data AND resets permissions before launching (logs the user out; removes downloads/settings). Only use when a true clean-install state is explicitly wanted.
Optional hardening: since clearState also resets permissions, consider requiring an explicit opt-in flag (or a confirmation) for the wipe path rather than folding it into a "launch" verb at all.
Environment
- Trailblaze source build (
v20260630...), driving a physical Android device. - Behavior is in shared/common code (
LaunchAppTrailblazeTool.kt), so it's platform-agnostic for the default-mode issue.
(No PR — filing as a report with the exact change inline.)
- Dominant language
- Kotlin
- Stars
- 313
- Forks
- 28
- Avg merge
- 15h 47m
- Merged PRs (30d)
- 4
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from block/trailblaze
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
block/trailblaze#184 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
block/trailblaze#126 ·
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
block/trailblaze#248 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 78/100
block/trailblaze#215 ·
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
block/trailblaze#214 ·
All issues in block/trailblaze
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bitcoindevkit/bdk-ffi#1125 ·
-
helsemelding-json-schema json-schema-core
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
contributor: external needs review
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100