Skip to content

[BUG] Translation error due to HTTP 429 rate-limiting on client=gtx Google Translate endpoint #64

Description

@chiconcota

Submission checklist

  • I have searched existing issues and confirmed this is not a duplicate.
  • I am using the latest available version of Noctalia.

Bug description

Summary

When using the `/tr` command with `noctalia/translator`, translation queries fail and

display a generic "Translation error" card.

### Environment
- **OS**: Linux
- **Noctalia version**: Latest (`noctalia-git`)
- **Plugin**: `noctalia/translator` (v1.0.5)

### Steps to Reproduce
1. Open Noctalia Launcher.
2. Type any translation query, for example: `/tr vi silent` or `/tr es hello`.
3. Wait for the debounce / API response.

### Observed Behavior
Instead of the translated result, the launcher displays a warning card:
- **Title**: `Translation error`
- **Subtitle**: `<query text>`

### Root Cause Analysis
In `translator/translator.luau`:
```lua
local url = `[https://translate.google.](https://translate.google.com/translate_a/single?client=gtx&sl=auto&tl=)

com/translate_a/single?client=gtx&sl=auto&tl={noctalia.string.
urlEncode(target)}&dt=t&q={noctalia.string.urlEncode(text)}`

  1. HTTP 429 Rate Limiting on client=gtx:
    Google heavily rate-limits / flags automated queries using the generic unauthenticated
    client=gtx parameter. Testing the endpoint directly via curl confirms Google returns
    HTTP/2 429 Too Many Requests with an HTML captcha / bot detection page:
    HTTP/2 429
    ...

    We're sorry...


    ... but your computer or network may be sending automated queries. To protect our
    users, we can't process your request right now.

  2. Error Handling in Noctalia:
    • noctalia.http sets res.ok = true based on transport success (response.transportOk).
    • Because res.ok is true, the response body (which is HTML, not JSON) is passed to
    parseGoogle(res.body).
    • noctalia.json.decode(body) fails to parse the HTML string, returning nil, which
    triggers the generic onDone(nil, "Translation error").

Verification & Suggested Fix

Switching the client identifier from client=gtx to client=dict-chrome-ex (the identifier
used by the official Google Translate extension) resolves the rate-limiting block
immediately and returns HTTP 200 OK with the exact same JSON format:

# Test with client=dict-chrome-ex
$ curl -s "[https://translate.googleapis.com/translate_a/single?client=dict-chrome-](https://translate.googleapis.com/translate_a/single?client=dict-chrome-ex&sl=auto&tl=vi&dt=t&q=silent)

ex&sl=auto&tl=vi&dt=t&q=silent"
[[["im lặng","silent",null,null,10]],null,"en",null,null,null,1,[],[["en"],null,[1],
["en"]]]

Proposed Diff (translator/translator.luau):

--- a/translator/translator.luau
+++ b/translator/translator.luau
@@ -80,11 +80,11 @@ local function parseGoogle(body)
 end

 local function fetchGoogle(text, target, onDone)
-  local url = `[https://translate.google.](https://translate.google.com/translate_a/single?client=gtx&sl=auto&tl=)

com/translate_a/single?client=gtx&sl=auto&tl={noctalia.string.
urlEncode(target)}&dt=t&q={noctalia.string.urlEncode(text)}+ local url =https://translate.googleapis.com/translate_a/single?client=dict-chrome-
ex&sl=auto&tl={noctalia.string.urlEncode(target)}&dt=t&q={noctalia.string.
urlEncode(text)}`
noctalia.http({ url = url }, function(res)
- if not res.ok then
+ if not res.ok or res.status ~= 200 then
onDone(nil, "Connection error — is the network up?")
return
end
local translated = parseGoogle(res.body)
if translated then

---

Steps to reproduce

  1. super +r
  2. type /tr vi
  3. error

Expected behavior

type hello --> xin chào

Actual behavior

error

Logs / error output


Noctalia version

v5

Compositor

Niri

Distribution

Arch-based

Environment information

-`                     chiconcota@archlinux
                 .o+`                    --------------------
                `ooo/                    OS: Arch Linux x86_64
               `+oooo:                   Kernel: Linux 6.18.48-1-lts
              `+oooooo:                  Uptime: 2 hours, 6 mins
              -+oooooo+:                 Packages: 4 (flatpak), 1277 (pacman)
            `/:-:++oooo+:                Shell: fish 4.8.1
           `/++++/+++++++:               Display (V2408S): 1920x1080 in 24", 60 Hz [External]
          `/++++++++++++++:              Window Manager: niri 26.04 (Wayland)
         `/+++ooooooooooooo/`            Icons: breeze-dark [Qt]
        ./ooosssso++osssssso+`           Font: DejaVu Sans (12pt) [Qt]
       .oossssso-`/ossssss+`          Cursor: default (24px)
      -osssssso.      :ssssssso.         Terminal: ghostty 1.3.1-arch2
     :osssssss/        osssso+++.        Terminal Font: JetBrainsMono Nerd Font (12pt)
    /ossssssss/        +ssssooo/-        CPU: AMD Ryzen 3 2200G (4) @ 3.50 GHz
  `/ossssso+/:-        -:/+osssso+-      GPU: AMD Radeon Vega 8 Graphics [Integrated]
 `+sso+:-`                 `.-/+oso:     Memory: 3.51 GiB / 13.57 GiB (26%)
`++:.                           `-/+/    Swap: 36.00 KiB / 19.04 GiB (0%)
.`                                 `/    Disk (/): 78.26 GiB / 115.83 GiB (68%) - ext4
                                         Disk (/mnt/Data): 43.44 GiB / 228.17 GiB (19%) - ext4
                                         Local IP (enp5s0): 192.168.1.57/24
                                         Locale: en_US.UTF-8

Additional context

            -`                     chiconcota@archlinux
             .o+`                    --------------------
            `ooo/                    OS: Arch Linux x86_64
           `+oooo:                   Kernel: Linux 6.18.48-1-lts
          `+oooooo:                  Uptime: 2 hours, 6 mins
          -+oooooo+:                 Packages: 4 (flatpak), 1277 (pacman)
        `/:-:++oooo+:                Shell: fish 4.8.1
       `/++++/+++++++:               Display (V2408S): 1920x1080 in 24", 60 Hz [External]
      `/++++++++++++++:              Window Manager: niri 26.04 (Wayland)
     `/+++ooooooooooooo/`            Icons: breeze-dark [Qt]
    ./ooosssso++osssssso+`           Font: DejaVu Sans (12pt) [Qt]
   .oossssso-````/ossssss+`          Cursor: default (24px)
  -osssssso.      :ssssssso.         Terminal: ghostty 1.3.1-arch2
 :osssssss/        osssso+++.        Terminal Font: JetBrainsMono Nerd Font (12pt)
/ossssssss/        +ssssooo/-        CPU: AMD Ryzen 3 2200G (4) @ 3.50 GHz

/ossssso+/:- -:/+osssso+- GPU: AMD Radeon Vega 8 Graphics [Integrated] +sso+:- .-/+oso: Memory: 3.51 GiB / 13.57 GiB (26%)
++:. -/+/ Swap: 36.00 KiB / 19.04 GiB (0%)
. / Disk (/): 78.26 GiB / 115.83 GiB (68%) - ext4
Disk (/mnt/Data): 43.44 GiB / 228.17 GiB (19%) - ext4
Local IP (enp5s0): 192.168.1.57/24
Locale: en_US.UTF-8

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions