#23326: fix(daemon): graceful degradation on unsupported platforms
gateway
size: XS
Cluster:
Cross-Platform Fixes
## Summary
- Problem: `resolveGatewayService()` throws a fatal `Error` on any platform other than darwin/linux/win32. Node.js on Android returns `process.platform === "android"`, causing every command that calls this function to crash.
- Why it matters: The gateway runs fine on Android/Termux as a foreground process — only service management (systemd/launchd/schtasks) is unsupported. The throw is disproportionate.
- What changed: Added Android/Termux detection and a no-op `GatewayService` implementation that degrades gracefully instead of throwing.
- What did NOT change: All existing platform paths (darwin/linux/win32) are untouched.
## Change Type
- [x] Bug fix
## Scope
- [x] Gateway / orchestration
## Linked Issue/PR
- Closes # (none — discovered during Android testing)
## User-visible / Behavior Changes
On Android/Termux, service management commands now print a helpful message instead of crashing. Gateway runs normally via `openclaw gateway`.
## Security Impact
- New permissions/capabilities? No
- Secrets/tokens handling changed? No
- New/changed network calls? No
- Command/tool execution surface changed? No
- Data access scope changed? No
## Repro + Verification
### Environment
- OS: Android 14 (Samsung Galaxy)
- Runtime: Termux 0.118.3, Node v24.13.0
- Model/provider: anthropic/claude-opus-4-6
- Integration/channel: Telegram
### Steps
1. Install openclaw on Android via Termux (no proot, no Linux layer)
2. Run `openclaw doctor` or `openclaw gateway start`
3. Observe fatal throw before patch
### Expected
- Commands degrade gracefully with a helpful message
### Actual (before patch)
- `Error: Gateway service install not supported on android` — fatal, exits immediately
## Evidence
- [x] Trace/log snippets
Before:
Error: Gateway service install not supported on android
at resolveGatewayService (dist/service-BfiYAV1H.js)
After:
openclaw doctor ✓ completes fully
openclaw gateway ✓ listening on ws://127.0.0.1:18789
Telegram: ok (@bot) (1948ms)
## Human Verification
- Verified: `doctor` completes without error, `gateway` runs and accepts connections, Telegram channel connects and responds
- Edge cases checked: `gateway start`, `gateway status`, `reset` — all degrade gracefully
- Not verified: Windows/macOS/Linux paths (untouched)
## Compatibility / Migration
- Backward compatible? Yes
- Config/env changes? No
- Migration needed? No
## Failure Recovery
- Revert: remove the `isAndroidTermux()` check and `resolveAndroidService()` function from `src/daemon/service.ts`
- No config changes to restore
## Risks and Mitigations
- Risk: False positive Android detection on non-Android linux systems
- Mitigation: Detection requires either `TERMUX_VERSION` env var (Termux-specific) or `OPENCLAW_PLATFORM=android-termux` (explicit opt-in) or `process.platform === "android"` (only true on actual Android Node builds). Standard Linux systems are unaffected.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Added Android/Termux platform support by detecting the platform via `TERMUX_VERSION`, `OPENCLAW_PLATFORM=android-termux`, or `process.platform === "android"` and returning a no-op `GatewayService` implementation instead of throwing.
Major changes:
- Added `isAndroidTermux()` helper to detect Android/Termux environments
- Added `resolveAndroidService()` that returns a gracefully degrading `GatewayService` with no-op implementations
- Early return in `resolveGatewayService()` for Android before checking other platforms
Issues found:
- The `noop` function signature doesn't match the expected `GatewayService` interface - it ignores `args.stdout` and writes directly to `process.stdout` instead
<h3>Confidence Score: 4/5</h3>
- Safe to merge after fixing the stdout parameter handling
- The change is well-scoped and adds proper platform detection for Android/Termux. The logic is sound and follows existing patterns. However, there's a minor but important inconsistency where the noop functions ignore the `args` parameter and write directly to `process.stdout` instead of using `args.stdout` like the other platform implementations do. This should be fixed to maintain consistency and ensure output routing works correctly.
- src/daemon/service.ts needs the noop function signature corrected
<sub>Last reviewed commit: 3bcf5b9</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#7060: fix: handle uv_interface_addresses failure on Android/Termux
by kjoh94 · 2026-02-02
78.6%
#11147: fix(daemon): stop gateway by port when no daemon service is active
by jasonthewhale · 2026-02-07
77.6%
#23584: fix(daemon): improve gateway service detection to avoid false posit...
by mohandshamada · 2026-02-22
76.4%
#13084: fix(daemon): multi-layer defense against zombie gateway processes
by openperf · 2026-02-10
76.3%
#23666: fix(doctor): openclaw-browser.service falsely flagged as duplicate ...
by yinghaosang · 2026-02-22
75.6%
#13321: android/gateway: harden manual connect identity and A2UI UX
by m888m · 2026-02-10
75.2%
#8311: feat(gateway): add SYSTEM_COMMANDS to Android node allowlist
by ipv1337 · 2026-02-03
74.7%
#11205: Android: fix gateway connection and canvas URL for Tailscale serve
by emonty · 2026-02-07
74.5%
#5496: Fix: Windows path separators stripped in Gateway scheduled task
by giuliozelante · 2026-01-31
74.5%
#5441: fix(android): resolve WebSocket handshake race condition (#1922)
by cortexuvula · 2026-01-31
74.3%