diff --git a/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkSpeakClient.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkSpeakClient.kt index 88d0b79b0e6..e11750d795e 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkSpeakClient.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkSpeakClient.kt @@ -41,7 +41,7 @@ internal class TalkSpeakClient( if (!response.ok) { val error = response.error val message = error?.message ?: "talk.speak request failed" - return if (isFallbackEligible(error?.details?.reason)) { + return if (isFallbackEligible(error)) { TalkSpeakResult.FallbackToLocal(message) } else { TalkSpeakResult.Failure(message) @@ -74,7 +74,9 @@ internal class TalkSpeakClient( ) } - private fun isFallbackEligible(reason: String?): Boolean { + private fun isFallbackEligible(error: GatewaySession.ErrorShape?): Boolean { + val reason = error?.details?.reason + if (reason == null) return true return reason == "talk_unconfigured" || reason == "talk_provider_unsupported" || reason == "method_unavailable" diff --git a/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkSpeakClientTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkSpeakClientTest.kt index 139403953d8..3d086465d19 100644 --- a/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkSpeakClientTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkSpeakClientTest.kt @@ -103,4 +103,26 @@ class TalkSpeakClientTest { val result = client.synthesize(text = "Hello", directive = null) assertTrue(result is TalkSpeakResult.Failure) } + + @Test + fun fallsBackWhenGatewayOmitsReason() = runTest { + val client = + TalkSpeakClient( + requestDetailed = { _, _, _ -> + GatewaySession.RpcResult( + ok = false, + payloadJson = null, + error = + GatewaySession.ErrorShape( + code = "INVALID_REQUEST", + message = "unknown method: talk.speak", + details = null, + ), + ) + }, + ) + + val result = client.synthesize(text = "Hello", directive = null) + assertTrue(result is TalkSpeakResult.FallbackToLocal) + } }