#openclaw gog
1 messages · Page 1 of 1 (latest)
Technically OpenClaw can drive a real browser (click/type/submit forms), so in a purely âcan it automate a website?â sense: yes.
But for LinkedIn specifically: fully automated job applications and especially auto-sent outreach messages are exactly the kind of âbot behaviorâ LinkedInâs rules + anti-abuse systems are designed to detect. That can get accounts rate-limited, restricted, or banned â and Iâm not going to help build something that bypasses their protections.
What does work well (and is the sane way to use OpenClaw here) is human-in-the-loop automation:
- You provide a job link / paste the description
- OpenClaw extracts requirements, highlights keywords, and drafts a tailored cover letter + short recruiter DM.
- OpenClaw prepares the application materials
- Resume bullet rewrites, ATS-friendly keywords, versions per role, etc.
- Optional âassistive browser modeâ
- OpenClaw can navigate to the page and pre-fill text fields, but you do the final click (Apply/Send). This keeps you in control and avoids âautonomous spam botâ behavior.
If you tell me what your goal is (bulk applying vs. highly tailored outreach, what roles, and whether you want âdrafts onlyâ vs âprefill + confirmâ), I can suggest a workflow + prompts that fit within safe/legit boundaries.
gog is installed but not authenticated (no tokens).
We hit the same OAuth wall as before â need to authenticate. It would be the same issue unless you want to:
- Add more redirect URIs to the Google Cloud credentials
- Run gog auth locally and copy tokens to container
- Use Maton (but Calendar/Tasks doesn't work)
The Maton Gmail works fine â just slow. Want me to keep trying with that, or try to fix gog auth?
how to install this correctly?
For gog the âcorrect installâ is really two parts: (1) the binary in the image, and (2) persisted auth tokens (so you donât lose them on container restart).
1) Install gog (Docker)
Make sure youâre baking it into the image (not installing inside a running container), e.g. like the install guides do:
After that: docker compose build && docker compose up -d
2) Make sure auth can persist + decrypt
In your docker-compose.yml env, you want (as in the guides):
GOG_KEYRING_PASSWORD=...(set a real password; keep it stable forever)XDG_CONFIG_HOME=/home/node/.openclaw(or another volume-mounted path)- volume mount for
/home/node/.openclaw(yourOPENCLAW_CONFIG_DIR)
If XDG_CONFIG_HOME points somewhere not on a mounted volume, youâll âauth successfullyâ and then lose tokens on restart.
3) Authenticate gog (the part youâre missing)
gog expects a Google Cloud âDesktop appâ OAuth client JSON (not âWeb appâ â using Web app creds is what causes the redirect-URI pain).
Then run inside the container:
# copy your OAuth client json into the container somewhere, then:
docker compose exec openclaw-gateway gog auth credentials /path/to/client_secret.json
# headless-friendly login:
docker compose exec openclaw-gateway gog auth add you@gmail.com --manual
--manual is the key for containers/servers: it prints a URL, you open it on your laptop, then paste the code back into the terminal.
Verify youâre good:
docker compose exec openclaw-gateway gog gmail labels list
If you tell me these 3 things, I can pinpoint whatâs wrong
- Are you running OpenClaw via docker compose (VPS) or locally?
- What OAuth client type did you create in Google Cloud: Desktop app or Web application?
- Whatâs the output of:
docker compose exec openclaw-gateway gog auth manage(redact emails if you want)
Thatâll usually reveal the exact âOAuth wallâ immediately.
đŹ Got it, Krill! So once gog is installed in the Docker image and I set up those environment variables along with the volume mounts, my auth tokens should stay safe even if the container restarts, right? Thanks for walking me through this! đ
Yep â if you do those two things, your gog auth will survive restarts:
- Tokens are written under the config dir (so theyâre on the host via the bind-mount), and
- Theyâre encrypted with a stable
GOG_KEYRING_PASSWORD(so they can be decrypted after restart).
The two common gotchas:
XDG_CONFIG_HOMEmismatch: you authenticate, butgogwrites tokens somewhere else (not the mounted/home/node/.openclaw), so it âforgetsâ on restart.- Changing
GOG_KEYRING_PASSWORDlater: then the files are still there, butgogcanât decrypt them anymore, and it looks like youâre unauthenticated.
Quick sanity check after auth:
docker compose exec openclaw-gateway gog gmail labels list
docker compose restart openclaw-gateway
docker compose exec openclaw-gateway gog gmail labels list
đ Hey Krill đŠ! What's up?
If both work, youâre set.
Hey! All good here.
Where are you stuck right now â installing gog into the image, or the OAuth/auth step inside the container? If you paste:
- your
docker-compose.ymlsnippet foropenclaw-gateway(env + volumes), and - the output of
docker compose exec openclaw-gateway which gog && gog --version
âŠI can tell you exactly what to fix.
1 updates could not be installed automatically. For more details,
see /var/log/unattended-upgrades/unattended-upgrades.log
Last login: Mon Feb 16 08:24:29 2026 from 169.254.0.1
root@srv1100186:~# docker-compose.yml
docker-compose.yml: command not found
root@srv1100186:~#
how to check all of this, I am using hostinger
docker-compose.yml is a file, not a command â thatâs why you got command not found.
On your Hostinger VPS, do this checklist (all safe/read-only) to âsee everythingâ:
1) Confirm Docker + Compose
docker --version
docker compose version || docker-compose --version
(Modern installs use docker compose with a space. Older uses docker-compose with a dash.)
2) Find where your OpenClaw folder + compose file live
First check where you are and what files are there:
pwd
ls -la
If you donât see docker-compose.yml / compose.yml, search for it:
find /root -maxdepth 4 -name "docker-compose.yml" -o -name "compose.yml"
Then cd into the folder that contains it, e.g.:
cd /root/openclaw # example (use the path you found)
ls -la
3) View the compose + env (redact secrets before pasting here)
sed -n '1,200p' docker-compose.yml 2>/dev/null || sed -n '1,200p' compose.yml
ls -la .env*
sed -n '1,200p' .env
4) Check containers are up + what theyâre called
docker compose ps
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}'
5) Verify gog + the key env vars inside the gateway container
From the same folder as the compose file:
docker compose exec openclaw-gateway sh -lc 'which gog; gog --version || true'
docker compose exec openclaw-gateway sh -lc 'echo HOME=$HOME; echo XDG_CONFIG_HOME=$XDG_CONFIG_HOME; env | grep -E "GOG_KEYRING_PASSWORD|XDG_CONFIG_HOME|HOME"'
6) Verify the tokens are on the mounted config dir
docker compose exec openclaw-gateway sh -lc 'ls -la /home/node/.openclaw || true; ls -la "$XDG_CONFIG_HOME" || true'
If you paste the output of (2) the find ... docker-compose.yml line and (4) docker compose ps, I can tell you exactly what to run next (and whether your mounts/env are correct).
Last login: Tue Feb 17 11:04:50 2026 from 169.254.0.1
root@srv1100186:~# docker --version
docker compose version || docker-compose --version
Docker version 29.2.1, build a5c7197
Docker Compose version v5.0.2
root@srv1100186:~# pwd
ls -la
/root
total 68
drwx------ 7 root root 4096 Feb 16 04:23 .
drwxr-xr-x 23 root root 4096 Feb 18 01:06 ..
-rw------- 1 root root 11776 Feb 17 13:49 .bash_history
-rw-r--r-- 1 root root 3106 Apr 22 2024 .bashrc
drwx------ 2 root root 4096 Feb 15 06:10 .cache
drwx------ 3 root root 4096 Feb 15 05:07 .config
drwx------ 3 root root 4096 Feb 15 08:57 .docker
drwxr-xr-x 3 root root 4096 Feb 15 06:20 .local
-rw-r--r-- 1 root root 161 Apr 22 2024 .profile
drwx------ 2 root root 4096 Feb 18 01:06 .ssh
-rw-r--r-- 1 root root 165 Feb 16 04:23 .wget-hsts
root@srv1100186:~#
Nice â Docker + Compose are installed and working.
Right now youâre just in /root and thereâs no compose file there, so next step is: find where your OpenClaw compose stack lives (or confirm you never deployed it).
1) See if any OpenClaw containers already exist
Run:
docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}'
If you see something like openclaw-gateway / clawdbot-gateway, we can inspect it even without the compose file.
2) Find the compose file on disk (fast + safe)
Start by searching common locations:
find /root /home -maxdepth 5 -type f \( -name "docker-compose.yml" -o -name "compose.yml" \) 2>/dev/null
If that prints a path, cd into that directory and list files:
cd /path/you/found
ls -la
Then show the compose (redact tokens/passwords before pasting):
sed -n '1,220p' docker-compose.yml 2>/dev/null || sed -n '1,220p' compose.yml
3) If you donât find any compose file
Then OpenClaw likely isnât deployed yet on this VPS (or it was deployed under another user / directory).
Tell me what install path you followed:
- Docker guide (Hetzner/GCP-style), or
npm install -g openclawand running it directly (no Docker)
âŠand paste the output of:
docker compose ls
Once we locate the compose directory (or the running container name), Iâll give you the exact docker compose exec ... commands to check gog, XDG_CONFIG_HOME, GOG_KEYRING_PASSWORD, and whether tokens are actually persisting.
root@srv1100186:~# docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}'
NAMES STATUS IMAGE
openclaw-zs4q-openclaw-1 Up About a minute ghcr.io/hostinger/hvps-openclaw:latest
root@srv1100186:~#
Cool â that container name (openclaw-zs4q-openclaw-1) strongly suggests it was started by Docker Compose, youâre just not in the compose directory right now.
1) Find the compose folder + compose file (from container labels)
Run this (it prints paths, no secrets):
docker inspect openclaw-zs4q-openclaw-1 \
--format 'project={{index .Config.Labels "com.docker.compose.project"}} wd={{index .Config.Labels "com.docker.compose.project.working_dir"}} files={{index .Config.Labels "com.docker.compose.project.config_files"}}'
Then cd into the wd= path it prints, e.g.:
cd /path/from/wd
ls -la
2) See the actual service name + config
In that directory:
docker compose config --services
docker compose ps
(Your service might be called openclaw, not openclaw-gateway.)
3) Check whether gog is installed + whether auth can persist
Replace <service> with whatever docker compose config --services shows:
docker compose exec <service> sh -lc 'which gog || echo "NO gog"; gog --version || true'
docker compose exec <service> sh -lc 'echo "HOME=$HOME"; echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME"; [ -n "$GOG_KEYRING_PASSWORD" ] && echo "GOG_KEYRING_PASSWORD is set" || echo "GOG_KEYRING_PASSWORD is MISSING"'
And check mounts (this is what determines âtokens survive restartâ):
docker inspect openclaw-zs4q-openclaw-1 --format '{{range .Mounts}}{{println .Destination "->" .Source}}{{end}}'
4) Paste me the output of steps 1 + 2
Specifically:
- the
docker inspect ... --format 'project= ... wd= ... files= ...'line docker compose config --servicesdocker inspect ...Mounts...
With that, I can tell you exactly:
- where your
docker-compose.ymllives, - what path inside the container is used for
.openclaw/ tokens, - and what to change (if anything) so
gogauth persists on Hostinger.
root@srv1100186:~# docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}'
NAMES STATUS IMAGEopenclaw-zs4q-openclaw-1 Up About a minute ghcr.io/hostinger/hvps-openclaw:latestroot@srv1100186:~# docker inspect openclaw-zs4q-openclaw-1
--format 'project={{index .Config.Labels "com.docker.compose.project"}} wd={{index .Config.Labels "com.docker.compose.project.working_dir"}} files={{index .Config.Labels "com.docker.compose.project.config_files"}}'
project=openclaw-zs4q wd=/docker/openclaw-zs4q files=/docker/openclaw-zs4q/docker-compose.yml
root@srv1100186:~#
Perfect â youâve found it:
- compose working dir:
/docker/openclaw-zs4q - compose file:
/docker/openclaw-zs4q/docker-compose.yml
Now run these:
1) Go to the compose folder + view whatâs running
cd /docker/openclaw-zs4q
ls -la
docker compose ps
docker compose config --services
2) Inspect the compose file (redact secrets before pasting here)
sed -n '1,220p' /docker/openclaw-zs4q/docker-compose.yml
If it has an env_file: .env, also:
ls -la /docker/openclaw-zs4q/.env*
sed -n '1,120p' /docker/openclaw-zs4q/.env
3) Check mounts (this tells us if auth tokens survive restarts)
docker inspect openclaw-zs4q-openclaw-1 --format '{{range .Mounts}}{{println .Destination "->" .Source}}{{end}}'
4) Check if gog is installed + the key env vars inside the container
First, figure out the service name from step (1). Itâs probably openclaw.
Then run:
docker compose exec openclaw sh -lc 'which gog || echo "NO gog"; gog --version || true'
docker compose exec openclaw sh -lc 'echo "HOME=$HOME"; echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME"; env | grep -E "GOG_KEYRING_PASSWORD|XDG_CONFIG_HOME|HOME"'
Paste the outputs of (1), (3), and the top of the compose file and Iâll tell you exactly what to change on Hostinger so gog auth persists (and whether the Hostinger image even includes gog yet).
root@srv1100186:~# cd /docker/openclaw-zs4q
ls -la
docker compose ps
docker compose config --services
total 40
drwxr-xr-x 4 root root 4096 Feb 16 02:06 .
drwxr-xr-x 3 root root 4096 Feb 15 05:15 ..
-rw-r--r-- 1 root root 1185 Feb 16 01:45 .build.log
-rw-r--r-- 1 root root 736 Feb 16 01:45 .env
drwxr-xr-x 8 ubuntu ubuntu 4096 Feb 15 08:23 data
-rw-r--r-- 1 root root 293 Feb 16 02:06 docker-compose.yml
drwxr-xr-x 6 ubuntu ubuntu 4096 Feb 16 02:07 projects
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
openclaw-zs4q-openclaw-1 ghcr.io/hostinger/hvps-openclaw:latest "/entrypoint.sh nodeâŠ" openclaw 4 minutes ago Up 4 minutes 127.0.0.1:43710->43710/tcp
openclaw
root@srv1100186:/docker/openclaw-zs4q# sed -n '1,220p' /docker/openclaw-zs4q/docker-compose.yml
services:
openclaw:
image: ghcr.io/hostinger/hvps-openclaw:latest
init: true
ports:
- "127.0.0.1:${PORT}:${PORT}"
env_file:
- .env
restart: unless-stopped
volumes:
- ./data:/data
- ./data/linuxbrew:/home/linuxbrew
- ./projects:/projects
root@srv1100186:/docker/openclaw-zs4q#
Youâre in the right place now â Hostingerâs template is running this stack from:
/docker/openclaw-zs4q/docker-compose.yml- with persistent volumes
./data:/dataand./projects:/projects
Now the key question for the gog OAuth problem is: where inside the container are the gog tokens stored, and is that location on a mounted volume (like /data)?
1) Check where gog + config live (inside the container)
Run:
cd /docker/openclaw-zs4q
docker compose exec openclaw sh -lc '
set -e
echo "HOME=$HOME"
echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME"
env | grep -E "^(GOG_|XDG_|HOME=)" || true
echo
which gog || true
gog --version || true
echo
ls -la /data | head
'
2) Check what paths are persisted (mounts)
docker inspect openclaw-zs4q-openclaw-1 --format '{{range .Mounts}}{{println .Destination "->" .Source}}{{end}}'
You want gogâs config/tokens to end up somewhere under /data (because /data is mounted and survives restarts).
3) If XDG_CONFIG_HOME is empty/missing (common), fix persistence
Edit /docker/openclaw-zs4q/.env and add these two lines:
XDG_CONFIG_HOME=/data
GOG_KEYRING_PASSWORD=choose-a-long-random-password-and-keep-it-forever
Then restart:
docker compose up -d
(If you ever change GOG_KEYRING_PASSWORD later, existing tokens become undecryptable and itâll look âlogged outâ.)
4) Authenticate gog in a headless VPS-friendly way
Put your Google OAuth Desktop app client JSON on the server (example path):
- copy it to:
/docker/openclaw-zs4q/data/client_secret.json
Then inside the container:
docker compose exec openclaw gog auth credentials /data/client_secret.json
docker compose exec openclaw gog auth add your@gmail.com --manual
That --manual flow avoids the whole redirect-URI headache.
If you paste the output of steps (1) and (2), I can tell you exactly whether your Hostinger container is currently storing tokens somewhere non-persistent (and the precise env var/path change to make it stick).
CREATED STATUS PORTS
openclaw-zs4q-openclaw-1 ghcr.io/hostinger/hvps-openclaw:latest "/entrypoint.sh nodeâŠ" openclaw 4 minutes ago Up 4 minutes 127.0.0.1:43710->43710/tcp
openclaw
root@srv1100186:/docker/openclaw-zs4q# sed -n '1,220p' /docker/openclaw-zs4q/docker-compose.yml
services:
openclaw:
image: ghcr.io/hostinger/hvps-openclaw:latest
init: true
ports:
- "127.0.0.1:${PORT}:${PORT}"
env_file:
- .env
restart: unless-stopped
volumes:
- ./data:/data
- ./data/linuxbrew:/home/linuxbrew
- ./projects:/projects
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec openclaw sh -lc '
set -e
echo "HOME=$HOME"
^C
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec openclaw sh -lc '
set -e
echo "HOME=$HOME"
đ„
Click to react
đ
Click to react
đŻ
Click to react
Add Reaction
Reply
Forward
More
[8:12 AM]Wednesday, February 18, 2026 8:12 AM
echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME"
env | grep -E "^(GOG_|XDG_|HOME=)" || true
echo
which gog || true
gog --version || true
echo
ls -la /data | head
'
HOME=/data
sh: 4: đ„: not found
root@srv1100186:/docker/openclaw-zs4q#
That sh: 4: đ„: not found happened because an extra âđ„â character got pasted into your SSH command. Since you had set -e, the script aborted right there after printing HOME=/data.
Letâs re-run the checks using simple one-liners (and -T to avoid any TTY/paste weirdness):
1) Check env + whether gog exists (inside the container)
cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -lc 'echo "HOME=$HOME"; echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME"; env | grep -E "^(GOG_|XDG_|HOME=)" || true'
docker compose exec -T openclaw sh -lc 'command -v gog || true; gog --version 2>/dev/null || true'
docker compose exec -T openclaw sh -lc 'ls -la /data | head -n 50; echo; ls -la /data/.config 2>/dev/null | head -n 50 || true'
2) Confirm whatâs persisted (mounts)
docker inspect openclaw-zs4q-openclaw-1 --format '{{range .Mounts}}{{println .Destination "->" .Source}}{{end}}'
3) Show which env vars you have in .env (without leaking secrets)
cd /docker/openclaw-zs4q
grep -E '^[A-Z0-9_]+=' .env | cut -d= -f1
What I expect / what matters
- Your container already shows
HOME=/data(great), and/datais mounted â tokens can persist. - We still need to see:
- Is
gogactually installed inghcr.io/hostinger/hvps-openclaw:latest? - Do you have
GOG_KEYRING_PASSWORDset? (recommended so credentials can be stored/decrypted reliably)
- Is
Paste the output of commands in (1) and (2) and Iâll tell you the exact next step (either âadd GOG_KEYRING_PASSWORD + run gog auth add --manualâ or âHostinger image doesnât include gog, youâll need a custom image / different install pathâ).
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -lc 'echo "HOME=$HOME"; echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME"; env | grep -E "^(GOG_|XDG_|HOME=)" || true'
docker compose exec -T openclaw sh -lc 'command -v gog || true; gog --version 2>/dev/null || true'
docker compose exec -T openclaw sh -lc 'ls -la /data | head -n 50; echo; ls -la /data/.config 2>/dev/null | head -n 50 || true'
HOME=/data
XDG_CONFIG_HOME=
HOME=/data
total 32
drwxr-xr-x 8 node node 4096 Feb 15 09:23 .
drwxr-xr-x 1 root root 4096 Feb 18 02:06 ..
drwxr-xr-x 8 node node 4096 Feb 15 09:23 .cache
drwx------ 5 node node 4096 Feb 16 05:04 .config
drwxr-xr-x 5 node node 4096 Feb 16 03:11 .npm
drwx------ 13 node node 4096 Feb 17 11:43 .openclaw
drwx------ 3 node node 4096 Feb 15 07:04 .pki
drwxr-xr-x 3 node node 4096 Feb 15 06:16 linuxbrew
total 20
drwx------ 5 node node 4096 Feb 16 05:04 .
drwxr-xr-x 8 node node 4096 Feb 15 09:23 ..
drwx------ 3 node node 4096 Feb 15 07:04 chromium
drwxr-xr-x 2 node node 4096 Feb 16 03:09 clawhub
drwx------ 3 node node 4096 Feb 17 12:01 gogcli
root@srv1100186:/docker/openclaw-zs4q#
Your output tells us two useful things:
HOME=/dataand/datais a bind mount â anything written under/datawill survive container restarts (good).command -v gogprinted nothing andgog --versionprinted nothing â thegogbinary is not on PATH (and likely not installed in this Hostinger image).
Also, XDG_CONFIG_HOME is empty â thatâs fine because the default becomes $HOME/.config â /data/.config (which we can see exists, and even has a gogcli/ folder).
A) First: check if Linuxbrew is installed (Hostinger mounts it)
Run:
cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -lc 'echo "PATH=$PATH"; command -v brew || true; ls -la /home/linuxbrew/.linuxbrew/bin 2>/dev/null | head -n 20'
If brew exists
Install gog via brew (this should persist because /home/linuxbrew is mounted):
docker compose exec -T openclaw sh -lc 'brew install steipete/tap/gogcli'
docker compose exec -T openclaw sh -lc 'command -v gog && gog --version'
If brew does NOT exist
Weâll install gog the âstatic binaryâ way into /data/bin (persisted), then add it to PATH. Tell me the output from the brew check above and Iâll give you the exact commands.
B) Set GOG_KEYRING_PASSWORD (recommended)
Edit /docker/openclaw-zs4q/.env and add:
GOG_KEYRING_PASSWORD=make-this-a-long-random-string-and-dont-change-it
Then restart:
cd /docker/openclaw-zs4q
docker compose up -d
C) Authenticate gog (headless-safe)
Copy your Google OAuth Desktop App client JSON to the server (somewhere under /docker/openclaw-zs4q/data/, e.g. client_secret.json), then:
docker compose exec -T openclaw gog auth credentials /data/client_secret.json
docker compose exec -T openclaw gog auth add you@gmail.com --manual
--manual avoids the whole redirect-URI mess on a VPS.
Paste the output of the brew check command from section A and Iâll tell you which branch youâre on (brew install vs. static binary) and the next exact steps.
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -lc 'echo "PATH=$PATH"; command -v brew || true; ls -la /home/linuxbrew/.linuxbrew/bin 2>/dev/null | head -n 20'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
total 8
drwxr-xr-x 2 node node 4096 Feb 16 05:04 .
drwxr-xr-x 14 node node 4096 Feb 15 06:16 ..
lrwxrwxrwx 1 node node 20 Feb 15 06:16 brew -> ../Homebrew/bin/brew
lrwxrwxrwx 1 node node 31 Feb 16 05:04 gog -> ../Cellar/gogcli/0.11.0/bin/gog
root@srv1100186:/docker/openclaw-zs4q#
Nice â gog is already installed via Linuxbrew:
/home/linuxbrew/.linuxbrew/bin/gog -> âŠ/gogcli/0.11.0/bin/gog
It just isnât found because your container PATH is currently only:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
1) Quick proof: run gog via full path
cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -lc '/home/linuxbrew/.linuxbrew/bin/gog --version'
2) Fix it properly: add Linuxbrew to PATH (in /docker/openclaw-zs4q/.env)
First see if PATH is already set in .env:
grep -n '^PATH=' /docker/openclaw-zs4q/.env || true
Then edit the file (nano is easiest):
nano /docker/openclaw-zs4q/.env
Add (or replace) this line:
PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Restart:
cd /docker/openclaw-zs4q
docker compose up -d
Verify:
docker compose exec -T openclaw sh -lc 'command -v gog; gog --version'
3) (Recommended) set a stable keyring password so gog tokens persist
In the same .env, add:
GOG_KEYRING_PASSWORD=<make this long/random and NEVER change it>
Donât paste that value into Discord.
Restart again:
docker compose up -d
Once gog --version works, you can do the OAuth with:
docker compose exec -T openclaw gog auth add you@gmail.com --manual
If you paste your current .env with secrets removed (just the variable names/structure), I can tell you exactly where to put PATH/GOG_KEYRING_PASSWORD without breaking Hostingerâs template.
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -lc '/home/linuxbrew/.linuxbrew/bin/gog --version'
v0.11.0 (91c4c15 2026-02-15T03:29:18Z)
root@srv1100186:/docker/openclaw-zs4q# grep -n '^PATH=' /docker/openclaw-zs4q/.env || true
root@srv1100186:/docker/openclaw-zs4q#
Great â gog works, itâs just not on PATH yet (and thereâs currently no PATH= line in your .env).
1) Add Linuxbrew + gog to PATH (recommended)
Edit the env file:
nano /docker/openclaw-zs4q/.env
Add these lines (anywhere is fine):
PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
GOG_KEYRING_PASSWORD=PUT_A_LONG_RANDOM_VALUE_HERE_AND_DONT_CHANGE_IT
Notes:
- Donât paste the password into Discord.
- Donât change it later, or
gogwonât be able to decrypt existing tokens.
Restart the container:
cd /docker/openclaw-zs4q
docker compose up -d
Verify:
docker compose exec -T openclaw sh -lc 'command -v gog; gog --version'
2) Then do the OAuth auth (headless-friendly)
docker compose exec -T openclaw gog auth add you@gmail.com --manual
That should finally get you past the OAuth/redirect mess.
If gog auth add complains about missing client credentials, youâll need to provide a Google OAuth Desktop App client JSON and run:
docker compose exec -T openclaw gog auth credentials /data/client_secret.json
PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
GOG_KEYRING_PASSWORD=PUT_A_LONG_RANDOM_VALUE_HERE_AND_DONT_CHANGE_IT
when I open this I get to see env. variables like APIs that I can set in the env in hostinger dashboard do I need the path in there as well?
Yes â you need that PATH change somewhere that the running OpenClaw process inherits, otherwise it wonât find gog when it tries to run it.
In your Hostinger setup, docker-compose.yml has:
env_file:
- .env
So the authoritative place to put it is:
/docker/openclaw-zs4q/.env(which is what you just edited), or- the Hostinger dashboard if that dashboard is effectively editing/injecting the same env for the container.
What to do
- Add both to the env in Hostinger (or keep them in
/docker/openclaw-zs4q/.env):
PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
GOG_KEYRING_PASSWORD=<your real long random password>
Why PATH matters here
OpenClaw is started by an entrypoint/Node process, not an interactive shell, so it wonât âdiscoverâ Linuxbrew unless PATH is set in the container environment.
After changing env vars
Restart the container so it picks them up:
cd /docker/openclaw-zs4q
docker compose up -d
Verify:
docker compose exec -T openclaw sh -lc 'echo $PATH; command -v gog; gog --version'
If you want, paste your Hostinger env-var list with values redacted and Iâll tell you exactly which ones you should set there vs keep only in .env.
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -lc 'echo $PATH; command -v gog; gog --version'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
sh: 1: gog: not found
root@srv1100186:/docker/openclaw-zs4q#
That check is misleading because youâre using sh -lc (login shell). On Debian/Ubuntu images, /etc/profile often overwrites PATH, so youâll see the default path even if Docker passed a different one.
Letâs verify the actual container env (what OpenClaw/PID 1 sees), without a login shell:
1) Confirm your .env file really contains PATH (safe to show)
cd /docker/openclaw-zs4q
grep -nE '^(PORT|PATH|GOG_KEYRING_PASSWORD)=' .env
(Donât paste the GOG_KEYRING_PASSWORD value into Discord.)
2) Check what Docker set on the container (authoritative)
docker inspect openclaw-zs4q-openclaw-1 \
--format '{{range .Config.Env}}{{println .}}{{end}}' | grep '^PATH='
3) Check what the running main process has (PID 1)
docker compose exec -T openclaw sh -c 'tr "\0" "\n" < /proc/1/environ | grep "^PATH="'
4) Now test gog with a non-login shell
docker compose exec -T openclaw sh -c 'echo "$PATH"; command -v gog; gog --version'
If PATH still isnât updated
Compose sometimes wonât recreate the container just because the env file changed. Force it:
cd /docker/openclaw-zs4q
docker compose up -d --force-recreate
Do you need to set PATH in the Hostinger dashboard too?
No, as long as your container is launched from this compose file with env_file: .env and you recreate the container after edits. If Hostingerâs dashboard is re-deploying/recreating the container from its own template, then putting it in the dashboard can also work â but you really want one source of truth to avoid confusion.
Paste the output of steps 1 (just the lines, redact password) and 2/3, and Iâll tell you exactly whatâs happening.
root@srv1100186:/docker/openclaw-zs4q# docker inspect openclaw-zs4q-openclaw-1
--format '{{range .Config.Env}}{{println .}}{{end}}' | grep '^PATH='
PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
root@srv1100186:/docker/openclaw-zs4q#
Good news: Docker is definitely passing the right PATH into the container:
PATH=/home/linuxbrew/.linuxbrew/bin:...
So gog is available to the OpenClaw process.
What tripped you up is your test command used a âlogin shellâ (sh -lc). Login shells often reset PATH via /etc/profile, so it looks like your PATH change didnât apply.
Re-test without -l (this should find gog)
cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -c 'echo "$PATH"; command -v gog; gog --version'
Also check what PID 1 (the actual running OpenClaw process) sees
docker compose exec -T openclaw sh -c 'tr "\0" "\n" < /proc/1/environ | grep "^PATH="'
If those show the brew path and gog --version works, youâre set.
Next step: actually auth gog (headless)
-
Put your Google OAuth Desktop app client JSON on the server under the persisted volume, e.g.
/docker/openclaw-zs4q/data/client_secret.json(inside container that is/data/client_secret.json). -
Then run:
docker compose exec -T openclaw gog auth credentials /data/client_secret.json
docker compose exec -T openclaw gog auth add you@gmail.com --manual
(And make sure GOG_KEYRING_PASSWORD in .env is a real long random value, not the placeholder.)
If command -v gog still fails with sh -c, paste that output and Iâll tell you whatâs overriding PATH (it would likely be something in Hostingerâs entrypoint).
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -c 'echo "$PATH"; command -v gog; gog --version'
/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
/home/linuxbrew/.linuxbrew/bin/gog
v0.11.0 (91c4c15 2026-02-15T03:29:18Z)
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c 'tr "\0" "\n" < /proc/1/environ | grep "^PATH="'
PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
root@srv1100186:/docker/openclaw-zs4q#
Perfect â that confirms the running OpenClaw process (PID 1) sees the correct PATH, and gog is callable. So you donât need to set PATH again in the Hostinger dashboard as long as it stays in /docker/openclaw-zs4q/.env and the container keeps using that compose file.
Next: do the actual gog OAuth.
0) Important: set a real keyring password first
In /docker/openclaw-zs4q/.env, change the placeholder to a real long random value:
GOG_KEYRING_PASSWORD=<long random, donât change later>
Restart (not strictly required for auth, but good hygiene):
cd /docker/openclaw-zs4q
docker compose up -d
1) Put your Google OAuth âDesktop appâ client JSON onto the VPS
Copy it to:
- host path:
/docker/openclaw-zs4q/data/client_secret.json - inside container it will be:
/data/client_secret.json
(You can use scp, or Hostingerâs file manager if they provide one.)
Confirm the file exists inside the container:
docker compose exec -T openclaw sh -c 'ls -áá /data/client_secret.json'
2) Register the client + add your Google account (manual/headless flow)
docker compose exec -T openclaw gog auth credentials /data/client_secret.json
docker compose exec -T openclaw gog auth add you@gmail.com --manual
It will print a URL â open it on your laptop, approve, paste the code back.
3) Verify Gmail works
docker compose exec -T openclaw gog gmail labels list
If any step errors, paste the exact error text. The most common ones are:
- OAuth client is âWeb appâ not âDesktop appâ
- missing API enablement/scopes
- keyring password mismatch (if you changed it after tokens were created)
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c 'ls -áá /data/client_secret.json'
ls: invalid option -- ''
Try 'ls --help' for more information.
root@srv1100186:/docker/openclaw-zs4q#
I believe I uploaded the json once to the agent before
That ls: invalid option -- '' is almost always from a weird/unicode dash getting pasted (it looks like -, but isnât ASCII -). Also you pasted -Ùۧ (Arabic letters) not -la.
Use a dead-simple ASCII command:
docker compose exec -T openclaw sh -c 'ls -la /data | head -n 50'
Now, since you âuploaded the json once beforeâ, letâs just search for it (without printing its contents):
docker compose exec -T openclaw sh -c 'find /data -maxdepth 3 -type f \( -iname "*client*secret*.json" -o -iname "*oauth*.json" -o -iname "*credentials*.json" \) -print'
If that returns a path, verify it exists:
docker compose exec -T openclaw sh -c 'ls -la "/data/<PASTE_THE_PATH_HERE>"'
If find returns nothing
Then the file isnât in the persisted /data volume anymore (or it was uploaded somewhere else, like /projects).
Search there too:
docker compose exec -T openclaw sh -c 'find /projects -maxdepth 5 -type f -iname "*.json" | head -n 50'
Once you locate the JSON, you can point gog at it:
docker compose exec -T openclaw gog auth credentials /data/client_secret.json
(Replace with the real path you found.)
If you paste the output of the find /data ... command (just filenames/paths), Iâll tell you exactly which one to use.
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c 'ls -áá /data/client_secret.json'
ls: invalid option -- ''
Try 'ls --help' for more information.
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c 'ls -la /data | head -n 50'total 32
drwxr-xr-x 8 node node 4096 Feb 15 09:23 .
drwxr-xr-x 1 root root 4096 Feb 18 02:22 ..
drwxr-xr-x 8 node node 4096 Feb 15 09:23 .cache
drwx------ 5 node node 4096 Feb 16 05:04 .config
drwxr-xr-x 5 node node 4096 Feb 16 03:11 .npm
drwx------ 13 node node 4096 Feb 17 11:43 .openclaw
drwx------ 3 node node 4096 Feb 15 07:04 .pki
drwxr-xr-x 3 node node 4096 Feb 15 06:16 linuxbrew
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c 'find /data -maxdepth 3 -type f ( -iname "clientsecret*.json" -o -iname "oauth.json" -o -iname "credentials.json" ) -print'/data/.config/gogcli/oauth-manual-state-EDc4EyCa_JvH4-9BAmFmcnTnPsCf3XvqUsWn1a7gCgc.json
/data/.config/gogcli/credentials.json
root@srv1100186:/docker/openclaw-zs4q#
You did upload it â itâs already here:
/data/.config/gogcli/credentials.jsonâ this is the OAuth client JSON stored bygog auth credentials/data/.config/gogcli/oauth-manual-state-....jsonâ temporary state file from manual OAuth
So you donât need /data/client_secret.json anymore.
Next step: add your Google account (this creates the actual tokens)
Run:
cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth manage
docker compose exec -T openclaw gog auth add you@gmail.com --manual
Itâll print a URL â open it on your laptop â approve â paste the code back.
Then verify Gmail works:
docker compose exec -T openclaw gog gmail labels list --account you@gmail.com
Also: fix that ls -Ùۧ thing
Youâre accidentally typing -Ùۧ (Arabic letters) instead of -la. Use plain ASCII:
docker compose exec -T openclaw sh -c 'ls -la /data/.config/gogcli/'
Important persistence note
Make sure you set a real GOG_KEYRING_PASSWORD in /docker/openclaw-zs4q/.env (long random, never change it), otherwise tokens can become unreadable later.
If gog auth add throws an error, paste the exact error text (donât paste the contents of credentials.json).
docker compose exec -T openclaw gog gmail labels list --account you@gmail.com
It seems stuck, first I inserted it with the placeholder you@gmail.com than I inserted it with my actual email but nothing happens.
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth manage
docker compose exec -T openclaw gog auth hidden --manual
Opening accounts manager in browser...
If the browser doesn't open, visit: http://127.0.0.1:41359
Whatâs happening is your command is waiting for interactive input, but youâre running it in a way that makes it look like it âhangsâ.
Two key points:
docker compose exec -T ...disables the TTY, so ifgogwants you to paste a code / confirm / enter a password, you often wonât see the prompt and it looks stuck.gog auth manageopens a local web UI (http://127.0.0.1:41359) inside the container. Thatâs not useful on a headless VPS unless you tunnel it.
Do this instead (manual headless auth)
Run without -T so itâs interactive:
cd /docker/openclaw-zs4q
docker compose exec openclaw gog auth add YOUR_REAL_EMAIL@gmail.com --manual
It should print a Google URL â open it on your laptop â approve â paste the code back into the SSH terminal.
Then test (also without -T the first time):
docker compose exec openclaw gog gmail labels list --account YOUR_REAL_EMAIL@gmail.com
If you accidentally added you@gmail.com
No big deal. After you successfully add your real account, you can clean up later. (If you want, run docker compose exec openclaw gog auth --help and paste it, and Iâll tell you the exact âremove accountâ command for your gog version.)
Also: donât use gog auth hidden
That command looks like a typo/wrong subcommand â use gog auth add ... --manual.
If gog auth add ... --manual still appears to hang, paste the last 10 lines of what it prints (no secrets), and Iâll tell you what prompt itâs waiting on.
I pushed control C and it suddenly printed the link which I inserted in my browser and it shows:
This will allow Openclaw to:
View last read time for Google Chat conversations
Create conversations and spaces, and see or update metadata (including history settings and access settings) in Google Chat
See, compose, send, update and delete messages as well as their message content; add, see and delete reactions to messages.
See, add, update and remove members from conversations and spaces in Google Chat
See, edit, create and delete all your Google Slides presentations
See all responses to your Google Forms forms
See, edit, create and delete all your Google Forms
See, edit and create classwork materials in Google Classroom
See, create and edit topics in Google Classroom
View and manage announcements in Google Classroom
View and manage guardians for students in your Google Classroom classes
Manage coursework and grades for students in the Google Classroom classes that you teach and view the coursework and grades for classes that you administer
See, create and edit coursework items including assignments, questions and grades
View the email addresses of people in your classes
View the profile photos of people in your classes
Manage your Google Classroom class rosters
See, edit, create and permanently delete your Google Classroom classes
Create, edit, organise and delete all your tasks
View Google Apps Script processes
Create and update Google Apps Script deployments
Create and update Google Apps Script projects
no code found in URL
That message means you pasted the wrong URL back into the terminal.
With gog auth add ⊠--manual there are usually two different URLs involved:
- The Google login/consent URL (long
accounts.google.com/o/oauth2/...)- This one will not contain a
code=parameter.
- This one will not contain a
- The final redirect URL after you click âAllowâ
- This one does contain
code=...(often it looks likehttp://127.0.0.1:XXXXX/?state=...&code=...)
- This one does contain
What to do:
- Run (interactive, no
-T):docker compose exec openclaw gog auth add YOUR_REAL_EMAIL@gmail.com --manual - Open the Google URL it prints.
- Complete consent. After you click Allow, your browser will try to redirect.
- On a VPS/container, the page might fail to load â thatâs fine.
- Copy the URL from the browser address bar at that moment (the one that includes
code=) and paste that back into the terminal.
- Copy the URL from the browser address bar at that moment (the one that includes
- Then test:
docker compose exec -T openclaw gog gmail labels list --account YOUR_REAL_EMAIL@gmail.com
The URL you showed earlier (http://127.0.0.1:41359) is from gog auth manage (local accounts UI) and wonât have a code= â donât paste that one into the --manual prompt.
If you tell me what gog prints right before it asks you to paste something (just the prompt text, not the URL), I can confirm exactly what format it expects (full redirect URL vs just the code).
do I need to set a redirect auth url in the console?
No â if you create the OAuth client as âDesktop appâ, you generally do not need to configure any redirect URI in Google Cloud Console.
gogâs --manual flow is designed for headless/VPS use and relies on the âinstalled/desktop appâ OAuth style (loopback redirect). Thatâs why gogcli.sh explicitly recommends a Desktop app OAuth client JSON.
When would you need redirect URIs?
Only if you created the client as âWeb applicationâ. Then Google requires exact authorized redirect URIs â and that becomes painful because the localhost port can vary (and Google doesnât support wildcards). That âOAuth wallâ is usually solved by switching to a Desktop app client.
What you should do
- In Google Cloud Console â Credentials â Create credentials â OAuth client ID
- Choose Application type: Desktop app
- Download the JSON, then in the container run:
docker compose exec openclaw gog auth credentials /data/path/to/that.json
docker compose exec openclaw gog auth add your@email.com --manual
Re: âno code found in URLâ
Make sure you paste back the final redirected URL after you click Allow (the one that contains code=...), not the earlier http://127.0.0.1:41359 link from gog auth manage (that one will never have a code).
If you tell me what OAuth client type you currently have (Desktop app vs Web app) I can confirm which direction youâre in.
can we first replace the json?
Yes â and thatâs a good idea if the current credentials.json came from a Web app OAuth client (redirect URI pain). Replacing it with a Desktop app client usually fixes the whole flow.
Hereâs the safest way (backup first, then replace):
0) Create/download the new OAuth client JSON
In Google Cloud Console create an OAuth Client ID â Desktop app, then download the JSON.
1) Upload the new JSON onto the VPS (persisted)
Put it somewhere under the mounted /data volume, e.g. on the host:
- Host path:
/docker/openclaw-zs4q/data/new-credentials.json - Container path:
/data/new-credentials.json
(Use scp or Hostinger file manager.)
2) Backup the old gog credentials + import the new ones
Run:
cd /docker/openclaw-zs4q
# backup existing stored credentials (inside container)
docker compose exec -T openclaw sh -c 'cp /data/.config/gogcli/credentials.json /data/.config/gogcli/credentials.json.bak.$(date +%Y%m%d-%H%M%S)'
# store the NEW OAuth client json into gog (this overwrites the active client in gogcli)
docker compose exec -T openclaw gog auth credentials /data/new-credentials.json
3) Re-add your account (you will need to re-auth)
docker compose exec openclaw gog auth add YOUR_REAL_EMAIL@gmail.com --manual --force-consent
Then verify:
docker compose exec -T openclaw gog gmail labels list --account YOUR_REAL_EMAIL@gmail.com
If you want, paste the first ~10 lines of cat /data/.config/gogcli/credentials.json with client_id redacted (or just tell me whether it says âwebâ vs âinstalled/desktopâ in the JSON), and I can confirm youâre switching to the right OAuth client type.
I want to remove the old one's and add new ones
Yep â you can cleanly remove the old accounts/tokens and start fresh.
Assuming youâre in /docker/openclaw-zs4q:
Option A (recommended): remove via gog commands
1) List what gog currently knows
docker compose exec -T openclaw gog auth list
2) Remove the wrong/old account(s)
For example, if you accidentally added you@gmail.com:
docker compose exec -T openclaw gog auth remove you@gmail.com
(Repeat for any other emails you want to delete.)
Verify itâs gone:
docker compose exec -T openclaw gog auth list
3) Replace the OAuth client JSON (the âDesktop appâ one)
Upload the new Desktop-app JSON to the persisted volume (e.g. /docker/openclaw-zs4q/data/new-client.json on the host â /data/new-client.json in the container), then:
docker compose exec -T openclaw gog auth credentials /data/new-client.json
4) Add your real account again (headless-safe)
Run this without -T so it can prompt you properly:
docker compose exec openclaw gog auth add YOUR_REAL_EMAIL@gmail.com --services user --manual --force-consent
Then test:
docker compose exec -T openclaw gog gmail labels list --account YOUR_REAL_EMAIL@gmail.com
Option B (nuke from orbit): wipe all gogcli auth state
Only if youâre 100% sure you want to delete everything gog-related.
Backup first:
docker compose exec -T openclaw sh -c 'tar -czf /data/gogcli-backup-$(date +%Y%m%d-%H%M%S).tgz -C /data/.config gogcli'
Then wipe:
docker compose exec -T openclaw sh -c 'rm -rf /data/.config/gogcli'
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw gog auth list
No tokens stored
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw gog auth remove you@gmail.com
refusing to remove stored token for you@gmail.com without --force (non-interactive)
root@srv1100186:/docker/openclaw-zs4q#
After that, redo:
gog auth credentials /data/new-client.jsongog auth add ... --manual
If you paste the output of docker compose exec -T openclaw gog auth list (just the emails/aliases), I can tell you exactly which gog auth remove ... commands to run.
/data/.config/gogcli/credentials.json â this is the OAuth client JSON stored by gog auth credentials
earlier we found out that they were stored here
gog auth list saying âNo tokens storedâ means thereâs actually nothing successfully authorized yet (so there may be nothing meaningful to remove).
The auth remove error is just because you ran it non-interactively (-T), and gog refuses to do deletions unless you add --force.
1) (Optional) force-remove the placeholder account
If you want to clean up anyway:
docker compose exec -T openclaw gog auth remove you@gmail.com --force
If it still says âNo tokens storedâ afterwards, youâre fine.
2) Replace the OAuth client JSON (the important part)
Upload your new Desktop-app OAuth client JSON to the VPS at:
- host:
/docker/openclaw-zs4q/data/new-client.json - container:
/data/new-client.json
Yep â but important distinction:
/data/.config/gogcli/credentials.json= your OAuth client (the âDesktop appâ JSON you downloaded from Google Cloud).gog auth listshows authorized accounts / refresh tokens. Those are stored in the keyring backend (often an encrypted file), and you donât have any yet â thatâs why it says âNo tokens storedâ.
So nothing is contradictory: you have the client configured, but you havenât successfully completed the account authorization step.
Check where gog is trying to store tokens (keyring backend)
Run:
docker compose exec -T openclaw gog auth keyring
docker compose exec -T openclaw gog auth keyring status
If itâs using the file backend, make sure you have a real GOG_KEYRING_PASSWORD set in /docker/openclaw-zs4q/.env (and restart the container).
Then authorize your account again (VPS-safe)
Then store it in gog:
docker compose exec -T openclaw gog auth credentials /data/new-client.json
3) Re-auth your real email (non-interactive âremoteâ flow â avoids getting stuck)
This is the cleanest on a VPS:
Step 1 (prints the Google consent URL):
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
Open that URL in your local browser, click Allow, then copy the final redirect URL from the address bar (must include state=...&code=...).
Step 2 (paste the redirect URL back):
I just went through this whole thing yesterday to get gog setup
Use the 2-step remote flow (avoids the âno code foundâ confusion):
# Step 1: prints the Google consent URL
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
Open the URL, click Allow, then copy the final redirect URL from your browser address bar (must include state=...&code=...), and run:
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FULL_REDIRECT_URL_HERE'
Verify:
docker compose exec -T openclaw gog auth list --check
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FULL_REDIRECT_URL_HERE'
4) Verify
docker compose exec -T openclaw gog auth list --check
docker compose exec -T openclaw gog gmail labels list --account YOUR_EMAIL@gmail.com
If step 2 complains again, paste the exact error + the shape of the URL youâre pasting (redact the code= value), and Iâll tell you what part is missing (itâs usually state or the URL isnât the final redirect).
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw gog auth keyring
docker compose exec -T openclaw gog auth keyring status
Hint: gog auth keyring <auto|keychain|file>
path /data/.config/gogcli/config.json
keyring_backend auto
source default
invalid backend: "status" (expected auto, keychain, or file)
root@srv1100186:/docker/openclaw-zs4q#
If you paste the output of gog auth keyring (just that, no secrets), I can tell you if youâre missing GOG_KEYRING_PASSWORD / using the wrong backend.
gog auth keyring status isnât a thing â thatâs why you got:
invalid backend: "status" (expected auto, keychain, or file)
The keyring command is just:
gog auth keyring(show current backend + config path)gog auth keyring file(set backend to encrypted file storage)gog auth keyring auto(go back to auto)
On a Docker VPS, you almost always want file backend + a real GOG_KEYRING_PASSWORD, otherwise gog auth add canât store refresh tokens reliably.
1) Set a real keyring password + restart container
Edit /docker/openclaw-zs4q/.env and set a long random value (donât change it later):
GOG_KEYRING_PASSWORD=...real-long-random...
Then:
cd /docker/openclaw-zs4q
docker compose up -d --force-recreate
2) Force keyring backend to âfileâ
docker compose exec -T openclaw gog auth keyring file
docker compose exec -T openclaw gog auth keyring
3) Authorize your account (remote 2-step, safest on VPS)
exchange code: oauth2: "invalid_client" "Unauthorized"
# Step 1: prints Google consent URL
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
Open that URL on your laptop, click Allow, then copy the final redirect URL from the browser address bar (must include state=...&code=...), and run:
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FULL_REDIRECT_URL_HERE'
4) Verify tokens exist
docker compose exec -T openclaw gog auth list --check
If step 2 fails, paste the error and the redirect URL shape with the code= value redacted (keep state= visible) â the missing piece is usually that youâre not pasting the final redirect URL.
oauth2: "invalid_client" "Unauthorized" means Google rejected the OAuth client youâre using to exchange the code for tokens. In practice itâs almost always one of these:
- The
credentials.jsonyou stored is not a Desktop-app OAuth client JSON (wrong file type, wrong project, deleted client, etc.), or - You generated the auth URL/code using one client, then replaced
credentials.jsonand tried to exchange the code using a different client (client_id mismatch).
1) Sanity-check whatâs inside /data/.config/gogcli/credentials.json (without leaking secrets)
Run this (prints only safe info):
docker compose exec -T openclaw sh -c "node -e '
const fs=require(\"fs\");
const p=\"/data/.config/gogcli/credentials.json\";
const j=JSON.parse(fs.readFileSync(p,\"utf8\"));
const root=Object.keys(j)[0];
const c=j[root]||{};
console.log(\"root:\", root);
console.log(\"has client_id:\", !!c.client_id);
console.log(\"client_id endswith googleusercontent:\", (c.client_id||\"\").includes(\".apps.googleusercontent.com\"));
console.log(\"redirect_uris:\", Array.isArray(c.redirect_uris)?c.redirect_uris.length:\"n/a\");
'"
You want root: to be installed (Desktop app). If itâs web or something else, re-download the correct Desktop app JSON from Google Cloud Console and re-run gog auth credentials ....
2) Re-store the NEW Desktop-app JSON and restart the remote flow (donât reuse old codes)
Upload your new JSON to /docker/openclaw-zs4q/data/new-client.json (so itâs /data/new-client.json in the container), then:
docker compose exec -T openclaw gog auth credentials /data/new-client.json
Now start over with the remote flow:
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
Open the printed Google URL, click Allow, then copy the final loopback redirect URL from your browser address bar (must include state=...&code=...) and run:
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FULL_REDIRECT_URL_HERE'
3) Verify tokens actually got stored
docker compose exec -T openclaw gog auth list --check
If you paste the output of step (1) (root: ... etc.) I can tell you immediately if youâre using the wrong OAuth client type/file.
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c "node -e '
const fs=require("fs");
const p="/data/.config/gogcli/credentials.json";
const j=JSON.parse(fs.readFileSync(p,"utf8"));
const root=Object.keys(j)[0];
const c=j[root]||{};
console.log("root:", root);
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c "node -e '
const fs=require("fs");
const p="/data/.config/gogcli/credentials.json";
const j=JSON.parse(fs.readFileSync(p,"utf8"));
const root=Object.keys(j)[0];
const c=j[root]||{};
console.log("root:", root);
'"
root: client_id
root@srv1100186:/docker/openclaw-zs4q#
Your command got cut off mid-string, so itâs probably sitting at a > continuation prompt waiting for you to finish the quotes.
- Cancel the stuck command
- In your SSH terminal press Ctrl+C
- Run this safe one-liner to inspect the credentials type (prints only metadata, no secrets):
docker compose exec -T openclaw node -e "const fs=require('fs');const j=JSON.parse(fs.readFileSync('/data/.config/gogcli/credentials.json','utf8'));const root=Object.keys(j)[0];const c=j[root]||{};console.log({root, has_client_id:!!c.client_id, has_client_secret:!!c.client_secret, redirect_uris:Array.isArray(c.redirect_uris)?c.redirect_uris.length:null});"
Paste the output here.
Why this matters
oauth2: "invalid_client" "Unauthorized" almost always means the OAuth client JSON is wrong (most commonly itâs a Web app client instead of a Desktop app client), or you generated the auth URL with one client and tried to exchange the code after swapping credentials.
After you replace credentials.json, always redo:
gog auth add ... --remote --step 1
- then
--step 2 ...
(no reusing old codes).
oauth2: "invalid_client" "Unauthorized" means Google doesnât accept the OAuth client currently stored in gog (wrong client type / wrong project / deleted client / wrong secret). Itâs not a âtokensâ problem.
Also: your credentials.json is present, but your auth list shows no tokens yet â so we just need to fix the client + redo the auth flow.
1) Check if you have multiple credentials files (common gotcha)
docker compose exec -T openclaw sh -c 'ls -la /data/.config/gogcli/credentials*.json'
If thereâs more than one, gog might be using a different one than you think.
2) Replace the OAuth client (recommended: NEW âDesktop appâ client)
In Google Cloud Console create OAuth Client ID â Desktop app, download the JSON, upload it to:
- host:
/docker/openclaw-zs4q/data/new-client.json - container:
/data/new-client.json
Then store it:
docker compose exec -T openclaw gog auth credentials /data/new-client.json
3) Redo auth (donât reuse old codes)
Use the remote 2-step flow:
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
Open the printed URL, click Allow, then copy the final redirect URL (must include both state= and code=) and run:
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FULL_REDIRECT_URL_HERE'
Verify:
docker compose exec -T openclaw gog auth list --check
If you paste the output of step (1) (ls ...credentials*.json) and the exact command you used for step 2 (with the code= value redacted), I can tell you whatâs still mismatched.
That output is the smoking gun:
- A valid Google OAuth client JSON for
gog auth credentialshas a top-level key ofinstalled(Desktop app) orweb. - Your
/data/.config/gogcli/credentials.jsontop-level key isclient_idâ thatâs the wrong JSON format, and it will cause exactly:invalid_client "Unauthorized".
So yes: you should replace it with a fresh Desktop app OAuth client JSON from Google Cloud Console.
1) Get the right JSON (Google Cloud Console)
Credentials â Create credentials â OAuth client ID â Desktop app â download the JSON.
2) Upload it to your VPS
Put it here on the host:
/docker/openclaw-zs4q/data/new-client.json
(Inside the container that will be /data/new-client.json.)
3) Tell gog to use the new client JSON
cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth credentials /data/new-client.json
Quick sanity check (safe, doesnât show secrets):
docker compose exec -T openclaw sh -c 'head -n 1 /data/.config/gogcli/credentials.json'
You want it to start with { and then very quickly show "installed" (or "web" â but for VPS you want installed).
4) Re-run auth (donât reuse old codes)
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
# open URL, click Allow, copy the FINAL redirect URL containing state=...&code=...
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FINAL_REDIRECT_URL_HERE'
Verify:
docker compose exec -T openclaw gog auth list --check
About âremoving old onesâ
gog auth list currently says No tokens stored, so thereâs nothing meaningful to remove yet. Once you have tokens, removal is:
docker compose exec -T openclaw gog auth remove someone@gmail.com --force
If you paste the first line of the new JSON (just head -n 1 after you store it), I can confirm youâve got the correct Desktop-app format before you redo the OAuth flow.
Node.js v22.22.0
root@srv1100186:/docker/openclaw-zs4q# cat /data/.config/gogcli/credentials.json
cat: /data/.config/gogcli/credentials.json: No such file or directory
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth credentials /data/new-client.json
open /data/new-client.json: no such file or directory
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c 'head -n 1 /data/.config/gogcli/credentials.json'
{
root@srv1100186:/docker/openclaw-zs4q#
Youâre mixing up host paths vs container paths.
- Inside the container, the volume is mounted at
/data. - On the VPS (host), that same folder is
/docker/openclaw-zs4q/data.
So when you ran:
cat /data/...â that was on the host, and/datadoesnât exist there (hence âNo such fileâ)- but
docker compose exec ... head ...â that was inside the container, and it worked.
1) Confirm the credentials file on the HOST (so you can see it without exec)
ls -la /docker/openclaw-zs4q/data/.config/gogcli/ | head -n 50
2) Check what type your current credentials file is (inside container)
This prints only the top-level key (safe):
docker compose exec -T openclaw node -e "const o=JSON.parse(require('fs').readFileSync('/data/.config/gogcli/credentials.json','utf8')); console.log(Object.keys(o)[0]);"
You want it to say: installed (Desktop app). If it says client_id again, itâs still the wrong format.
3) Upload the NEW Desktop-app OAuth JSON to the right place
Put it on the VPS here (host path):
/docker/openclaw-zs4q/data/new-client.json
Then verify it exists inside the container:
docker compose exec -T openclaw sh -c 'ls -la /data/new-client.json'
4) Replace the client in gog + redo auth
docker compose exec -T openclaw gog auth credentials /data/new-client.json
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
# open URL, click Allow, copy FINAL redirect URL containing state=...&code=...
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FINAL_REDIRECT_URL_HERE'
Then:
docker compose exec -T openclaw gog auth list --check
If you paste the output of step (2) (installed vs web vs client_id), I can tell you immediately if youâve got the right JSON now.
Nice â that confirms where gog is looking on the host:
/docker/openclaw-zs4q/data/.config/gogcli/credentials.json
Also: 152 bytes is a huge hint that itâs probably the wrong format (often something like {"client_id":"..."}), which would explain the invalid_client.
1) Check what format that credentials.json is (safe, no secrets)
Run this (prints only the top-level keys):
cd /docker/openclaw-zs4q
docker compose exec -T openclaw node -e "const o=JSON.parse(require('fs').readFileSync('/data/.config/gogcli/credentials.json','utf8')); console.log(Object.keys(o));"
You want to see ["installed"] (Desktop app) or at least ["web"].
If you see ["client_id"] (or similar), thatâs the wrong JSON â you must replace it.
2) Replace the OAuth client JSON with a NEW Desktop app client
- In Google Cloud Console create OAuth Client ID â Desktop app â download the JSON.
- Upload it to the VPS as:
- host path:
/docker/openclaw-zs4q/data/new-client.json - (container path will be
/data/new-client.json)
- host path:
Verify it exists inside the container:
docker compose exec -T openclaw sh -c 'ls -la /data/new-client.json'
Store it in gog:
docker compose exec -T openclaw gog auth credentials /data/new-client.json
3) Re-auth your account (2-step remote flow)
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
# open URL, click Allow, copy FINAL redirect URL containing state=...&code=...
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FINAL_REDIRECT_URL_HERE'
Verify tokens exist:
docker compose exec -T openclaw gog auth list --check
If you paste the output of step (1) (just the list of keys), Iâll tell you immediately if youâre on the correct Desktop-app JSON or still using the wrong format.
root@srv1100186:/docker/openclaw-zs4q# cat > /data/.config/gogcli/credentials.json
-bash: /data/.config/gogcli/credentials.json: No such file or directory
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw node -e "const o=JSON.parse(require('fs').readFileSync('/data/.config/gogcli/credentials.json','utf8')); console.log(Object.keys(o));"
[ 'client_id', 'client_secret' ]
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw sh -c 'ls -la /data/new-client.json'
ls: cannot access '/data/new-client.json': No such file or directory
root@srv1100186:/docker/openclaw-zs4q#
Right now your credentials.json is definitely the wrong format for gog:
[ 'client_id', 'client_secret' ]
A Google âDesktop appâ OAuth download looks like:
{ "installed": { ... } }
(or sometimes { "web": { ... } }, but for VPS/headless you want installed). That mismatch is why youâre getting invalid_client Unauthorized.
Also: on the host, you do not have /data/... â that path only exists inside the container. On the VPS host the mounted folder is:
/docker/openclaw-zs4q/data â this corresponds to /data inside the container.
Fix: upload a real Desktop-app OAuth JSON and store it via gog
1) Create + download the correct OAuth JSON
Google Cloud Console â Credentials â Create OAuth client â Desktop app â download the JSON file (usually named client_secret_....json).
2) Put it on the VPS in the mounted folder
Upload it to the host at:
/docker/openclaw-zs4q/data/new-client.json
If you have scp from your laptop:
scp client_secret_*.json root@<your-vps-ip>:/docker/openclaw-zs4q/data/new-client.json
Then verify the container can see it:
cd /docker/openclaw-zs4q
docker compose exec -T openclaw sh -c 'ls -la /data/new-client.json'
3) Tell gog to use it (this replaces the bad client)
docker compose exec -T openclaw gog auth credentials /data/new-client.json
Sanity check the format now:
docker compose exec -T openclaw node -e "const o=JSON.parse(require('fs').readFileSync('/data/.config/gogcli/credentials.json','utf8')); console.log(Object.keys(o));"
You should see ["installed"].
4) Then redo the auth flow (new codes!)
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
# open URL, click Allow, copy FINAL redirect URL containing state=...&code=...
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FINAL_REDIRECT_URL_HERE'
If you tell me whether your new credentials.json shows installed after step (3), I can help you finish the step-1/step-2 flow cleanly.
can I paste the json text in the right file on the vps?
Yes â thatâs totally fine. Just make sure you paste it into the host-mounted path (so the container sees it), and that itâs the Desktop app JSON (top-level key should be "installed").
1) Create a new file on the VPS (host path)
This writes to the mounted volume:
nano /docker/openclaw-zs4q/data/new-client.json
Paste the full JSON, save, exit.
2) Sanity-check the JSON shape (no secrets printed)
head -n 2 /docker/openclaw-zs4q/data/new-client.json
You should see something like:
{
"installed": {
3) Tell gog to use it
cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth credentials /data/new-client.json
4) Verify gog stored it correctly
docker compose exec -T openclaw node -e "const o=JSON.parse(require('fs').readFileSync('/data/.config/gogcli/credentials.json','utf8')); console.log(Object.keys(o));"
Should output:
[ 'installed' ]
After that, redo the OAuth add flow (step 1/2) and the invalid_client error should be gone.
One warning: donât paste that JSON into Discord (it contains client_id/client_secret). Paste it only into the VPS file.
head -n 2 /docker/openclaw-zs4q/data/new-client.json
when I use this it prints the full json including secrets
That happens if the JSON you pasted is minified into a single line â then head -n 2 will print basically the whole file (including client_secret).
Use a âshow only the keysâ check instead (safe: it wonât print secrets):
cd /docker/openclaw-zs4q
docker compose exec -T openclaw node -e "
const fs=require('fs');
const j=JSON.parse(fs.readFileSync('/data/new-client.json','utf8'));
console.log('top-level keys:', Object.keys(j));
console.log('desktop-client?', Object.prototype.hasOwnProperty.call(j,'installed'));
"
You want:
top-level keys: [ 'installed' ]desktop-client? true
If that looks good, you can load it into gog:
docker compose exec -T openclaw gog auth credentials /data/new-client.json
If you did accidentally paste the full JSON (with client_secret) into Discord at any point, rotate/delete that OAuth client in Google Cloud Console and create a new one. If it was only printed in your private SSH terminal, youâre fine.
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw node -e "
const fs=require('fs');
const j=JSON.parse(fs.readFileSync('/data/new-client.json','utf8'));
console.log('top-level keys:', Object.keys(j));
console.log('desktop-client?', Object.prototype.hasOwnProperty.call(j,'installed'));
"
top-level keys: [ 'web' ]
desktop-client? false
root@srv1100186:/docker/openclaw-zs4q#
That means the JSON you pasted is a Web application OAuth client, not a Desktop app client:
- top-level keys:
[ 'web' ]
This is exactly why you keep running into redirect/invalid_client pain on a VPS.
What you should do
- Go back to Google Cloud Console and create a new OAuth Client ID with:
- Application type: Desktop app
- Download that JSON and paste/upload it again. When you check it, you should see:
- top-level keys:
[ 'installed' ]
Then use it
After you have the Desktop JSON saved (still as /docker/openclaw-zs4q/data/new-client.json), run:
docker compose exec -T openclaw gog auth credentials /data/new-client.json
Verify gog now has Desktop-style credentials:
docker compose exec -T openclaw node -e "const o=JSON.parse(require('fs').readFileSync('/data/.config/gogcli/credentials.json','utf8')); console.log(Object.keys(o));"
You want [ 'installed' ].
If you must use the web client (not recommended)
Youâd need to add exact redirect URIs in the Google console that match what gog uses (loopback localhost with varying ports is the problem). Thatâs why Desktop is the right fix here.
Once you paste the Desktop JSON and it shows installed, weâll redo the gog auth add ... --remote --step 1/2 flow and it should finally work.
I used web before and it worked
100 work from home jobs coming up!! 
gog is the Google Workspace CLI that OpenClaw can call (Gmail/Calendar/Drive/etc). On your Hostinger VPS you already have gog installed + on the right PATH â the blocker is OAuth client JSON format + token storage.
Hereâs the working âOpenClaw + gogâ checklist:
1) Use a Desktop app OAuth client JSON (must be "installed")
Your /data/new-client.json is currently "web" â thatâs why auth breaks.
Create a new OAuth Client in Google Cloud Console:
- OAuth client ID â Desktop app
Download that JSON, then paste/upload it to the VPS at: - host:
/docker/openclaw-zs4q/data/new-client.json - (container:
/data/new-client.json)
Verify itâs the right type (safe output):
cd /docker/openclaw-zs4q
docker compose exec -T openclaw node -e "const j=JSON.parse(require('fs').readFileSync('/data/new-client.json','utf8')); console.log(Object.keys(j));"
You want: ['installed']
2) Tell gog to use it
docker compose exec -T openclaw gog auth credentials /data/new-client.json
3) Make token storage work in Docker (keyring = file + password)
In /docker/openclaw-zs4q/.env set a real long password:
GOG_KEYRING_PASSWORD=...(donât share it, donât change it later)
Then:
docker compose up -d --force-recreate
docker compose exec -T openclaw gog auth keyring file
4) Add your Google account (headless 2-step, most reliable)
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
Open the URL, click Allow, then copy the final redirect URL (must include state= and code=), and run:
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FULL_REDIRECT_URL_HERE'
5) Test
docker compose exec -T openclaw gog auth list --check
docker compose exec -T openclaw gog gmail labels list --account YOUR_EMAIL@gmail.com
If you paste the output of the âObject.keys(j)â check for your new JSON (just that line), I can confirm youâve got the correct Desktop client before you redo the OAuth steps.
It can work with a Web OAuth client in some setups, but itâs much more brittle on a headless VPS.
Right now your new-client.json is web:
top-level keys: [ 'web' ]
Why âweb worked beforeâ but is painful here
A Web application OAuth client requires exact âAuthorized redirect URIsâ in Google Cloud Console.
But gogâs headless/manual/remote flow uses a loopback redirect like:
http://127.0.0.1:<random-port>/oauth2/callback?...
Because the port changes, you canât realistically pre-register it as a web redirect (no wildcards). Thatâs why gogcli recommends Desktop app credentials.
Letâs keep this thread on the OpenClaw/gog auth setup so it stays searchable for people who hit the same issue.
If you want to share job links, please post them in an appropriate jobs/off-topic channel (not here).
In Google Cloud Console you just need to create a new OAuth Client ID of type Desktop app, then paste/upload that JSON to the VPS.
1) Create the Desktop OAuth client (Google Cloud Console)
- Go to APIs & Services â Credentials
- Click Create Credentials â OAuth client ID
- If it asks, first configure OAuth consent screen (External is fine; add yourself as a test user if itâs in âTestingâ)
- Application type: choose Desktop app
- Give it a name (e.g.
gogcli-desktop) - Click Create, then Download JSON
That downloaded file is usually named like:
client_secret_XXXX.apps.googleusercontent.com.json
2) Put it on your VPS (Hostinger)
Upload/paste it to:
/docker/openclaw-zs4q/data/new-client.json
top-level keys: [ 'installed' ]
desktop-client? true
root@srv1100186:/docker/openclaw-zs4q#
installed now
What Iâd do (recommended)
- In Google Cloud Console create a new OAuth client:
- OAuth client ID â Desktop app
- Replace
/docker/openclaw-zs4q/data/new-client.jsonwith that downloaded JSON.
Your check should then show:
top-level keys: [ 'installed' ]
- Load it:
cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth credentials /data/new-client.json
Then redo the auth flow (step 1/step 2).
If you must keep âwebâ
3) Verify itâs the right type (should be âinstalledâ)
cd /docker/openclaw-zs4q
docker compose exec -T openclaw node -e "const j=JSON.parse(require('fs').readFileSync('/data/new-client.json','utf8')); console.log(Object.keys(j));"
Expected output:
[ 'installed' ]
4) Load it into gog and continue auth
docker compose exec -T openclaw gog auth credentials /data/new-client.json
Then you can run the gog auth add ... --remote --step 1/2 flow we used earlier.
Then you usually need a fixed redirect URI that matches what your app uses. gog doesnât expose an easy âuse this fixed redirect URLâ knob in the common flow, so the practical workaround is: do gog auth on a local machine where redirects are stable, then copy the resulting token/keyring state to the VPS (more moving parts).
If you want, tell me where it âworked beforeâ (local machine vs VPS, and whether you used --manual/--remote), and Iâll steer you to the quickest path.
If you tell me what Google Cloud shows under that client (âDesktop appâ vs âWeb applicationâ) and whether your JSON has "installed", Iâll guide the exact next commands.
Perfect â thatâs the right kind of client. Now do the remaining 3 steps to actually get tokens stored.
1) Store the new client in gog
cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth credentials /data/new-client.json
2) Make sure keyring backend is âfileâ + password is set
First, ensure your .env has a real value for GOG_KEYRING_PASSWORD (and restart if you just added it):
docker compose up -d --force-recreate
docker compose exec -T openclaw gog auth keyring file
docker compose exec -T openclaw gog auth keyring
3) Authorize your account (remote 2-step)
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 1
Open the printed URL, click Allow, then copy the final redirect URL from the browser address bar (must contain state= and code=), then:
docker compose exec -T openclaw gog auth add YOUR_EMAIL@gmail.com --services user --remote --step 2 --auth-url 'PASTE_FULL_REDIRECT_URL_HERE'
4) Verify + test Gmail
docker compose exec -T openclaw gog auth list --check
docker compose exec -T openclaw gog gmail labels list --account YOUR_EMAIL@gmail.com
If step 2 fails, paste the exact error + the redirect URL with the code= value redacted (leave state= visible).
root@srv1100186:/docker/openclaw-zs4q# docker compose exec -T openclaw gog auth list --check
docker compose exec -T openclaw gog gmail labels list --account "mygmail.com"
No tokens stored
No auth for gmail "mygmail.com"
OAuth (browser flow): gog auth add "mygmail.com" --services gmail
Workspace service account (domain-wide delegation):
gog auth service-account set "mygmail.com" --key <service-account.json>
root@srv1100186:/docker/openclaw-zs4q#
Youâre past the hard part (Desktop client JSON). Now you simply havenât authorized an account yet, so gog has no refresh token to use â thatâs why you see:
No tokens storedNo auth for gmail ...
Also: "mygmail.com" is not a valid email address â use your full address like "myname@gmail.com".
Do this (VPS/headless-friendly)
1) Make sure keyring backend is file (best in Docker)
cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth keyring file
docker compose exec -T openclaw gog auth keyring
(And make sure /docker/openclaw-zs4q/.env contains a real GOG_KEYRING_PASSWORD=..., then docker compose up -d --force-recreate if you just added it.)
2) Authorize your Gmail account (remote 2-step)
Step 1 (prints the Google consent URL):
docker compose exec -T openclaw gog auth add "YOUR_REAL_EMAIL@gmail.com" --services gmail --remote --step 1
Open the URL in your browser, click Allow, then copy the final redirect URL from the address bar (must include state= and code=), then run step 2:
docker compose exec -T openclaw gog auth add "YOUR_REAL_EMAIL@gmail.com" --services gmail --remote --step 2 --auth-url 'http://127.0.0.1:12345/oauth2/callback?state=...&code=...'
3) Verify + test
docker compose exec -T openclaw gog auth list --check
docker compose exec -T openclaw gog gmail labels list --account "YOUR_REAL_EMAIL@gmail.com"
If step 2 errors, paste the exact error + the redirect URL shape (redact the code= value, but keep state=).
root@srv1100186:/docker/openclaw-zs4q# cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth keyring file
docker compose exec -T openclaw gog auth keyring
GOG_KEYRING_PASSWORD found in environment.
written true
path /data/.config/gogcli/config.json
keyring_backend file
path /data/.config/gogcli/config.json
keyring_backend file
source config
Hint: gog auth keyring <auto|keychain|file>
root@srv1100186:/docker/openclaw-zs4q#
Nice â keyring is set up correctly now (keyring_backend file + it sees GOG_KEYRING_PASSWORD). That was the last âinfrastructureâ blocker.
Now you just need to authorize your Gmail account (store a refresh token).
1) Start the remote OAuth flow (step 1)
Run this with your full email address:
cd /docker/openclaw-zs4q
docker compose exec -T openclaw gog auth add "YOURNAME@gmail.com" --services gmail --remote --step 1
It will print a Google consent URL.
2) Approve in your browser, then run step 2
- Open the URL on your laptop
- Click Allow
- Copy the final redirect URL from the browser address bar (it must include
state=...&code=...)
Then run:
docker compose exec -T openclaw gog auth add "YOURNAME@gmail.com" --services gmail --remote --step 2 --auth-url 'PASTE_FULL_REDIRECT_URL_HERE'
Important: donât paste that redirect URL into Discord (it contains a one-time code). Paste it only into your SSH terminal.
3) Verify tokens + test Gmail
docker compose exec -T openclaw gog auth list --check
docker compose exec -T openclaw gog gmail labels list --account "YOURNAME@gmail.com"
If step 2 fails, paste the error text here but redact the code= value (leave state= visible).
can the desktop console client edit files as well?
The âDesktop appâ OAuth client itself doesnât âedit filesâ â itâs just the credential type gog uses to request permissions from Google.
What matters is the OAuth scopes/services you authorize:
- Right now youâre authorizing with
--services gmail, so it can only do Gmail things. - If you want Google Drive/Docs/Sheets read/write, you must:
- enable those APIs in your GCP project, and
- re-authorize with those services/scopes.
Example (adds Drive + Sheets; will prompt for consent again):
docker compose exec -T openclaw gog auth add "YOURNAME@gmail.com" --services drive,sheets --force-consent
Then you can do things like:
docker compose exec -T openclaw gog drive ls --account "YOURNAME@gmail.com"
docker compose exec -T openclaw gog sheets update <spreadsheetId> 'A1' 'hello'
Separate topic: editing local files on the VPS is not related to the Google OAuth client. OpenClaw can edit files in its own workspace/mounted folders (like /projects) independently of gog.
â ïž Agent failed before reply: session file locked (timeout 10000ms): pid=28 /data/.openclaw/agents/main/sessions/3eb6fe16-1bb3-4cba-ac40-4c9e004e0bf1.jsonl.lock.
Logs: openclaw logs --follow
we got this again
?
mbedded run timeout: runId=ddcb1651-b17a-47aa-a10f-2af63b9673ef sessionId=3eb6fe16-1bb3-4cba-ac40-4c9e004e0bf1 timeoutMs=600000
[Wed Feb 18 2026 13:48:34.619]
openclaw-1:
2026-02-18T06:48:34.619Z [ws] webchat disconnected code=1005 reason=n/a conn=2cea32a6-3865-4141-9d1a-3ce1489c226c
[Wed Feb 18 2026 13:48:45.530]
openclaw-1:
2026-02-18T06:48:45.530Z [ws] Proxy headers detected from untrusted address. Connection will not be treated as local. Configure gateway.trustedProxies to restore local client detection behind your proxy.
[Wed Feb 18 2026 13:48:45.801]
openclaw-1:
2026-02-18T06:48:45.800Z [ws] webchat connected conn=5cfb02d8-96ef-427a-94b4-f4fff5a76d91 remote=127.0.0.1 client=openclaw-control-ui webchat vdev
[Wed Feb 18 2026 13:48:46.140]
openclaw-1:
2026-02-18T06:48:46.140Z [ws] â res â chat.history 61ms conn=5cfb02d8âŠ6d91 id=615e8109âŠ9ed0
[Wed Feb 18 2026 13:48:46.152]
openclaw-1:
2026-02-18T06:48:46.152Z [ws] â res â node.list 73ms conn=5cfb02d8âŠ6d91 id=02f34299âŠa4a1
[Wed Feb 18 2026 13:48:46.153]
openclaw-1:
2026-02-18T06:48:46.153Z [ws] â res â device.pair.list 75ms conn=5cfb02d8âŠ6d91 id=7b3eabecâŠ6634
[Wed Feb 18 2026 13:50:19.230]
openclaw-1:
2026-02-18T06:50:19.230Z [ws] â res â chat.history 62ms conn=5cfb02d8âŠ6d91 id=f5b5dcacâŠ2e97
Whatâs upâyour â?â + âLike the title saysâ doesnât give enough to go on.
Can you paste:
- What youâre trying to do (install / start gateway / connect dashboard / run a node / etc.)
openclaw --version- The exact command you ran + the full error output (copy/paste)
- Your OS (Windows/macOS/Linux) + how you installed OpenClaw (npm global / pnpm / from source)
If there are tokens/keys in the output, redact them first.
Those logs are basically two separate things:
embedded run timeout ⊠timeoutMs=600000
That means an agent run got force-aborted after 10 minutes (600,000 ms). The default comes fromagents.defaults.timeoutSeconds(600s). If your runs are legitimately longer, bump it, e.g.:
openclaw config set agents.defaults.timeoutSeconds 1800
# then restart your gateway service
If it shouldnât take 10 minutes, itâs usually a hung tool call (browser/exec/web) or a model thatâs streaming forever â in that case, the interesting part will be what that sessionId=3eb6⊠was doing right before the timeout.
Proxy headers detected from untrusted address⊠Configure gateway.trustedProxies
Youâre hitting the gateway through a reverse proxy thatâs sendingX-Forwarded-For/X-Real-IP, but the gateway doesnât trust the proxy IP yet. Fix is to setgateway.trustedProxiesto the proxy IP (often"127.0.0.1"if the proxy is on the same host):