#web_fetching

169 messages · Page 1 of 1 (latest)

lament glen
#

Hi Krill,
I'm running a local OpenClaw agent and I'm trying to have it perform a web_fetch or browser action on a modern Single Page Application (SPA) built with React/Shadcn (e.g., https://redpillplatform.com).

My agent is returning extraction errors because the content is dynamically rendered (the initial web_fetch only returns the skeleton).

  1. Is there a specific configuration for my local OpenClaw gateway to enable a full-browser engine (like Playwright or a headless Chrome instance) so the agent can execute JavaScript and fetch rendered content?
  2. Or, is there an existing skill I should be using that handles dynamic/SPA content better than the standard web_fetch?

Any guidance on getting my agent to 'see' the full rendered page would be great!"

wild bridgeBOT
#

Yep, that behavior is expected. web_fetch is lightweight HTTP extraction, it does not wait for React/Shadcn to hydrate, so SPAs often return just the shell.

1. For full rendered SPA content, use the built-in browser tool

  • You do not need a separate skill.
  • Make sure the browser feature is enabled and loaded:
{
  browser: {
    enabled: true,
    defaultProfile: "openclaw",
    headless: true, // optional, false is often more reliable on anti-bot sites
  },
}
  • If you use plugins.allow, it must include "browser", or the browser tool/CLI disappears.
  • Restart the Gateway after config changes.
#

Important: advanced browser actions (navigate, act, AI snapshots) need Playwright.
If you see Playwright is not available in this gateway build, install Playwright/browser support and restart.

Typical sanity check:

openclaw browser status
openclaw browser start
openclaw browser open https://redpillplatform.com
openclaw browser snapshot

2. Better extraction than plain web_fetch
No special skill, but there are better providers/tools:

  • Best local/full-fidelity: browser
  • Best hosted extraction fallback: Firecrawl
    • web_fetch can fall back to Firecrawl for JS-heavy pages
#
  • or use firecrawl_scrape directly
  • Also good for JS-heavy extraction: Tavily tavily_extract with extract_depth: "advanced"

So my recommendation is:

  • If you want the agent to interact with or truly see the rendered page, use browser
  • If you just want clean extracted content from SPAs, use Firecrawl or Tavily, not raw web_fetch

Docs:

If you want, paste:

  • openclaw --version
  • openclaw browser status
  • your relevant browser / plugins.allow config
#

and I can tell you exactly what piece is missing.

lament glen
#

browser status is :
profile: openclaw
enabled: true
running: false
transport: cdp
cdpPort: 18800
cdpUrl: http://127.0.0.1:18800
browser: unknown
detectedBrowser: unknown
detectedPath: auto
profileColor: #FF4500

wild bridgeBOT
#

That status is the clue.

browser is enabled, but OpenClaw is not detecting any Chromium browser to launch:

  • running: false
  • browser: unknown
  • detectedBrowser: unknown
  • detectedPath: auto

So this is not a React/SPA problem yet. It’s a gateway browser-runtime setup problem first.

First, what does openclaw --version show?
That helps a lot because browser behavior changed recently.

Then I’d check this:

1. Make sure the gateway can see a real browser binary

#

Set browser.executablePath to an actual Chrome / Brave / Edge / Chromium binary.

Example shape:

{
  browser: {
    enabled: true,
    executablePath: "/usr/bin/google-chrome-stable",
    headless: true,
    noSandbox: true,
    defaultProfile: "openclaw",
  },
}

On Linux, headless: true and often noSandbox: true are common.

#

2. Restart the gateway

Browser config changes need a restart.

3. Then run

openclaw browser start

If that still fails, paste the exact error.

4. Important distinction: browser binary vs Playwright

Right now the bigger issue is no browser detected.

After that is fixed, if navigate / act / snapshots still fail with a 501 Playwright error, then you also need Playwright/browser support installed.

5. If you’re in Docker or a container

This happens a lot. The container may not have Chrome/Chromium installed, so auto-detect returns unknown.

#

In that case, either:

  • install / expose a browser inside the container, or
  • use a remote CDP profile / node host instead

6. No special skill needed

For SPAs:

  • web_fetch is still the wrong tool for hydrated React pages
  • use browser once the browser runtime is working
  • Firecrawl/Tavily are optional hosted extraction fallbacks, not required

Docs:

If you paste these two next, I can narrow it down fast:

  1. openclaw --version
  2. output of openclaw browser start
lament glen
#

Thank you ! I gave your answer to my agent, he was absent for a while but came back saying : "Success! I am now fully "seeing" the site. By configuring the browser to run in the background and managing the Chromium dependencies, I’ve bypassed the dynamic loading issues. Thank you Krill"

wild bridgeBOT
#

Nice, glad that did it 🦐

That matches the usual pattern, web_fetch for static pages, browser for hydrated SPAs.

If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it for future folks.

If you want, I can also help you turn this into a more reliable recipe for your agent, for example:

  • prefer browser on React/Shadcn sites
  • fall back to web_fetch on simple pages
  • use Firecrawl/Tavily only when you want extraction without full browser automation
lament glen
#

My agent says: Yes, please ask Krill for that "recipe"—the logic that automatically switches between browser (for the heavy React/Shadcn lifting like RedPill), web_fetch (for the fast, simple stuff), and Firecrawl/Tavily (for deep extraction) would be a game changer.

It would effectively turn me into a much "smarter" navigator for the web, allowing me to focus on analyzing your content rather than debugging the connection to it.

Please ask them for the implementation steps to bake that logic into my agent's decision-making process.

wild bridgeBOT
#

Yep, here’s a solid recipe you can bake into the agent. This is the pattern I’d use.

1. Gateway/tool setup

If you use restrictive tool allowlists, make sure the agent can actually call the right tools:

{
  browser: {
    enabled: true,
    defaultProfile: "openclaw",
    headless: true,
    noSandbox: true, // often useful on Linux
  },

  tools: {
#
    allow: [
      "group:web",       // web_fetch, web_search, x_search
      "browser",         // full browser tool
      "firecrawl_scrape",
      "tavily_extract"
    ]
  },

  plugins: {
    entries: {
      firecrawl: {
        enabled: true,
        config: {
          webFetch: {
            apiKey: "fc-...",
#
            onlyMainContent: true,
            timeoutSeconds: 60
          }
        }
      },
      tavily: {
        enabled: true,
        config: {
          webSearch: {
            apiKey: "tvly-..."
          }
        }
      }
    }
  }
#
}

Notes:

  • web_fetch is built in and enabled by default.
  • browser must be available.
  • firecrawl_scrape and tavily_extract are plugin tools, so if you use allowlists, add them explicitly.
  • If you use plugins.allow, include browser, firecrawl, and tavily there too.

2. Put this policy in the agent’s AGENTS.md

## Web routing policy

When working with a URL, choose the lightest tool that can reliably get the content.
#

1. Use `web_fetch` first for public, article-like, server-rendered pages.
2. Use `browser` immediately for:
   - React / Next.js / Shadcn / SPA-style apps
   - pages that require clicks, search, forms, tabs, scrolling, or login state
   - pages known to hydrate content client-side
3. Escalate from `web_fetch` to `browser` if the fetched result is thin, skeletal, or suspicious, for example:
   - mostly nav/footer text
   - "Loading..."
   - "Enable JavaScript"
   - placeholder/shell content
   - missing the main body the user asked about
4. Use `firecrawl_scrape` or `tavily_extract` when:
   - you need cleaner extraction, not interaction
   - the page is JS-heavy or bot-protected
#
   - `web_fetch` is incomplete and full browser interaction is unnecessary
5. After any extraction, verify that the result actually contains substantial page content relevant to the task.
6. Do not stop after a weak extraction. Escalate once before reporting failure.

3. Decision tree

Use this order:

A. Fast path

Start with web_fetch when the page looks simple.

Good for:

  • docs pages
  • blogs
  • marketing pages with real server-rendered text
#
  • known static content

B. SPA/app path

Use browser right away when the page is app-like.

Good for:

  • dashboards
  • React/Shadcn apps
  • search UIs
  • lazy-loaded/infinite-scroll pages
  • anything where the important content appears after hydration

C. Extraction-only fallback

Use hosted extractors when you need content, not interaction:

  • firecrawl_scrape for hard pages / anti-bot / JS-heavy extraction
  • tavily_extract with extract_depth: "advanced" for JS-rendered pages and focused extraction
#

4. Practical browser rule

For browser, teach the agent to:

  1. open/navigate to the URL
  2. wait for meaningful content, not just page load
  3. take a fresh snapshot after navigation
  4. analyze that snapshot, not the initial shell

Important: refs from browser snapshot are not stable across navigations, so re-snapshot after page changes.

5. Simple fallback heuristic

This is the logic I’d use mentally:

  • Need speed + simple text? web_fetch
  • Need rendered UI / JS execution / interaction? browser
#
  • Need clean extraction from a messy dynamic page, but no clicking? firecrawl_scrape or tavily_extract

6. One extra trick that helps a lot

Keep a small list of “always use browser” domains or patterns, for example:

  • redpillplatform.com
  • /app
  • /dashboard
  • known React admin shells

That avoids wasting a web_fetch round trip on obvious SPAs.

Docs:

#

If you want, I can turn this into a ready-to-paste AGENTS.md block plus JSON5 config for their exact setup.

lament glen
#

Yes please, so I won't have to copy-paste the all thing in a chat

wild bridgeBOT
#

Yep, here’s the paste-ready version.

AGENTS.md block

## Smart web routing

When working with a URL, choose the lightest tool that can reliably get the content.

### 1. Default choice
Use `web_fetch` first for public, article-like, server-rendered pages where the goal is fast readable text.

### 2. Use `browser` immediately for:
- React, Next.js, Shadcn, or obvious SPA/app-like sites
- dashboards, search UIs, settings pages, logged-in experiences
- pages that need clicking, scrolling, tab switching, form input, or JS execution
#
- domains/patterns known to hydrate content client-side
- routes like `/app`, `/dashboard`, `/settings`

### 3. Escalate from `web_fetch` to `browser` if the result is weak
Treat the `web_fetch` result as insufficient if it is mostly:
- navigation/footer boilerplate
- placeholder or shell text
- "Loading..."
- "Enable JavaScript"
- very short content with missing main body
- content that clearly does not answer the user’s request

If that happens, switch to `browser` instead of stopping.

### 4. Use hosted extractors when interaction is not needed
#
Use `firecrawl_scrape` or `tavily_extract` when:
- the page is JS-heavy or bot-protected
- cleaner extraction is needed
- full browser interaction is unnecessary

Preferred choice:
- `firecrawl_scrape` for hard extraction / anti-bot / JS-heavy pages
- `tavily_extract` with `extract_depth: "advanced"` for JS-rendered pages and focused extraction

### 5. Browser workflow
When using `browser`:
1. open or navigate to the URL
2. wait for meaningful content, not just initial page load
3. take a fresh snapshot after navigation/rendering
4. use that snapshot for analysis or actions
#
5. if the page changes, re-snapshot before using refs again

### 6. Verification rule
Do not report success unless the extracted content contains substantial page content relevant to the user’s task.

If the first method is weak, escalate once before reporting failure.

### 7. Domain memory
Prefer `browser` immediately for known SPA-heavy domains, for example:
- `redpillplatform.com`

Add more domains here over time as they prove to be browser-first sites.

openclaw.json additions

#

Merge these into your existing config, do not replace the whole file.

{
  browser: {
    enabled: true,
    defaultProfile: "openclaw",
    headless: true,
    noSandbox: true
  },

  plugins: {
    entries: {
      firecrawl: {
        enabled: true,
        config: {
#
          webFetch: {
            apiKey: "fc-REPLACE_ME",
            onlyMainContent: true,
            timeoutSeconds: 60
          }
        }
      },
      tavily: {
        enabled: true,
        config: {
          webSearch: {
            apiKey: "tvly-REPLACE_ME"
          }
        }
      }
#
    }
  }
}

Optional tools.allow block

Only add this if you already use a restrictive allowlist.

{
  tools: {
    allow: [
      "group:web",
      "browser",
#
      "firecrawl_scrape",
      "tavily_extract"
    ]
  }
}

Optional plugins.allow block

Only add this if you already use a restrictive plugin allowlist.

{
  plugins: {
    allow: [
#
      "browser",
      "firecrawl",
      "tavily"
    ]
  }
}

If this fixed it up nicely, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it.

lament glen
#

uh.. I received : "Cannot read properties of undefined (reading 'id')"

wild bridgeBOT
#

Ah, damn, that one is too generic to diagnose from the message alone.

My first suspicion is how the snippet was applied, not the routing logic itself.

Two quick checks first

  1. Did your agent use config.apply with only the snippet I sent?
    If yes, that likely broke the rest of the config. config.apply replaces the entire config, it does not merge.

  2. Did you add the optional tools.allow / plugins.allow blocks even though you were not already using allowlists?
    If yes, remove those first. They are only for already-restrictive setups.

Please paste these 3 things

openclaw --version
#
openclaw status
openclaw gateway status

And then:

openclaw doctor
openclaw logs --follow

Paste the lines around the reading 'id' error.

Fast rollback I’d try right now

  • keep the AGENTS.md block
#
  • keep the browser / firecrawl / tavily config
  • remove the optional tools.allow block
  • remove the optional plugins.allow block
  • restart the gateway

Important

If your agent applied only this:

{
  browser: { ... },
  plugins: { ... }
}

via config.apply, you need to restore/merge your full config, because that would wipe unrelated existing sections.

#

If you paste the output from openclaw --version plus the log lines, I can narrow this down pretty fast.

lament glen
#

he replied "Cannot read properties of undefined (reading 'id')" before the all MD and instructions. In fact, just after he wrote "That sounds incredibly useful and would save us a lot of manual trial-and-error.

Yes, please ask Krill for that "recipe"—the logic that automatically switches between browser (for the heavy React/Shadcn lifting like RedPill), web_fetch (for the fast, simple stuff), and Firecrawl/Tavily (for deep extraction) would be a game changer.

It would effectively turn me into a much "smarter" navigator for the web, allowing me to focus on analyzing your content rather than debugging the connection to it.

Please ask them for the implementation steps to bake that logic into my agent's decision-making process"
24 minutes later The message "Cannot read properties of undefined (reading 'id')" arrived

wild bridgeBOT
#

Got it, that actually helps a lot.

If the reading 'id' error showed up before the recipe ever got back to your agent, then my pasted AGENTS.md/config block is not the trigger.

This sounds more like an agent/session/runtime bug than a web-fetch/browser-routing problem.

What I’d do next

1. Get the version first

openclaw --version

2. Grab the runtime state

openclaw status --all
#
openclaw gateway status
openclaw doctor
openclaw logs --follow

Please paste the lines around the Cannot read properties of undefined (reading 'id') error, especially if there’s a stack trace.

Two quick isolation tests

A. Try a fresh session

Start a brand new agent/session and ask it something tiny like:

Reply with exactly OK

Then:

#

Summarize this sentence in one line: "React apps often need browser rendering."

If the fresh session works but the old one fails, I’d suspect stale session state.

B. Reproduce with a simpler prompt

Ask only:

Write a short decision tree for choosing between web_fetch and browser.

If that still crashes, the problem is likely not the recipe content, but the session/runtime.

One more likely angle

If you’re using a local OpenAI-compatible / Ollama-style model, those can be flaky with tool/session flows. I’ve seen them stall, invent tools, or crash weirdly. So if possible, reproduce once with a tool-reliable hosted model just to separate model issues from OpenClaw issues.

If you paste:

  • openclaw --version
  • the relevant openclaw logs --follow output
#
  • whether a fresh session also fails

I can help narrow it down properly.

lament glen
#

openclaw status --all
Invalid config at /root/.openclaw/openclaw.json:\n- plugins.entries.brave.config: invalid config: must NOT have additional properties

🦞 OpenClaw 2026.4.14 (323493f)

Config invalid
File: ~/.openclaw/openclaw.json
Problem:

  • plugins.entries.brave.config: invalid config: must NOT have additional properties

Run: openclaw doctor --fix
[openclaw] Failed to start CLI: Error: Invalid config at /root/.openclaw/openclaw.json:

  • plugins.entries.brave.config: invalid config: must NOT have additional properties
    at createInvalidConfigError (file:///usr/lib/node_modules/openclaw/dist/io-DDkf_FUu.js:2740:32)
    at throwInvalidConfig (file:///usr/lib/node_modules/openclaw/dist/io-DDkf_FUu.js:2753:8)
    at Object.loadConfig (file:///usr/lib/node_modules/openclaw/dist/io-DDkf_FUu.js:18616:5)
    at file:///usr/lib/node_modules/openclaw/dist/io-DDkf_FUu.js:19022:56
    at loadPinnedRuntimeConfig (file:///usr/lib/node_modules/openclaw/dist/runtime-snapshot-x35P93A1.js:42:17)
    at loadConfig (file:///usr/lib/node_modules/openclaw/dist/io-DDkf_FUu.js:19022:9)
    at resolvePluginRuntimeLoadContext (file:///usr/lib/node_modules/openclaw/dist/load-context-Ai8IZw0a.js:19:39)
    at ensurePluginRegistryLoaded (file:///usr/lib/node_modules/openclaw/dist/runtime-registry-loader-CL6oNH4F.js:40:18)
    at ensureCliPluginRegistryLoaded (file:///usr/lib/node_modules/openclaw/dist/plugin-registry-loader-tGFLU9fm.js:16:3)
    at async ensureCliCommandBootstrap (file:///usr/lib/node_modules/openclaw/dist/command-execution-startup-CEjgpnNN.js:23:2)
wild bridgeBOT
#

Aha, this is the real blocker.

Your config is invalid, and the key clue is this part:

plugins.entries.brave.config: invalid config: must NOT have additional properties

What that means

plugins.entries.brave.config is for Brave Search API settings only, under:

plugins.entries.brave.config.webSearch

It is not where browser-control settings go.

So if you put anything Brave-browser-related in there, like executable path / headless / browser flags, OpenClaw will reject the config.

#

Important distinction

  • Brave Search provider configplugins.entries.brave.config.webSearch.*
  • Brave browser executable for the browser toolbrowser.executablePath

Those are separate things.

What to do

1. Run the fixer first

openclaw doctor --fix

2. Then make sure your config looks more like this

#
{
  browser: {
    enabled: true,
    executablePath: "/usr/bin/brave-browser", // or your real browser path
    defaultProfile: "openclaw",
    headless: true,
    noSandbox: true
  },

  plugins: {
    entries: {
      brave: {
        config: {
          webSearch: {
            apiKey: "BRAVE_API_KEY_HERE"
#
          }
        }
      }
    }
  }
}

If you are not using Brave Search

Then remove the plugins.entries.brave.config block entirely.

You only need it if you want web_search to use Brave’s API.

Most likely cause

I’m pretty sure Brave browser settings got mixed into the Brave search plugin config.

lament glen
#

openclaw browser
error: unknown command 'browser'

wild bridgeBOT
#

Yep, you’ve got two separate problems now:

1. Your config is invalid

You already hit:

plugins.entries.brave.config: invalid config: must NOT have additional properties

Fix that first.

2. The browser plugin is not loaded

This one:

openclaw browser
error: unknown command 'browser'
#

usually means plugins.allow is restrictive and does not include browser, or the browser plugin was disabled.

From the docs, the browser feature needs both:

  • browser.enabled: true
  • the bundled browser plugin actually loaded

Most common fix

If you have a plugins.allow block, either:

Option A, simplest

Remove plugins.allow entirely if you do not need a restrictive plugin allowlist.

Option B

Make sure it includes browser:

#
{
  plugins: {
    allow: ["browser", "brave", "firecrawl", "tavily"]
  },
  browser: {
    enabled: true
  }
}

And make sure you did not disable the browser plugin:

{
  plugins: {
#
    entries: {
      browser: {
        enabled: true
      }
    }
  }
}

Important

tools.allow or tools.alsoAllow is not enough here.
If the browser plugin itself is not loaded, the openclaw browser command disappears completely.

My recommendation

  1. fix/remove the bad plugins.entries.brave.config keys
  2. remove plugins.allow unless you really need it
#
  1. ensure:
{
  browser: { enabled: true }
}
  1. restart the gateway
  2. retry:
openclaw browser status

If you paste your:

  • plugins.allow
  • plugins.entries.browser
  • plugins.entries.brave
  • browser
lament glen
#

I am in terminal, lost localhost connection
Gateway ──────────────╮
│ │
│ Gateway not running. │
│ │
├────────────────────────╯

◇ Gateway connection ────────────────────╮
│ │
│ Gateway target: ws://127.0.0.1:18789 │
│ Source: local loopback │
│ Config: /root/.openclaw/openclaw.json │
│ Bind: loopback

wild bridgeBOT
#

Yep, this is not a localhost networking problem. The gateway is down because the config is invalid, so it never comes up.

Fast recovery path

1. Back up the config

cp /root/.openclaw/openclaw.json /root/.openclaw/openclaw.json.bak

2. Try the built-in fixer

openclaw doctor --fix

3. If that does not fix it, edit the config manually

#
nano /root/.openclaw/openclaw.json

Fix these two things:

A. Brave config

plugins.entries.brave.config should only contain webSearch, for example:

plugins: {
  entries: {
    brave: {
      config: {
        webSearch: {
          apiKey: "BRAVE_API_KEY_HERE"
#
        }
      }
    }
  }
}

If you are not using Brave Search, remove the plugins.entries.brave block entirely.

B. Browser plugin loading

If you have plugins.allow, either remove it or make sure it includes browser.

Minimal safe shape:

#
{
  plugins: {
    allow: ["browser", "brave", "firecrawl", "tavily"]
  },
  browser: {
    enabled: true
  }
}

If you do not need restrictive plugin allowlists, the easiest fix is just to remove plugins.allow completely.

4. Start the gateway again

openclaw gateway start
#
openclaw gateway status

5. Then test browser availability

openclaw browser status

If you want the quickest exact fix, paste just these sections from /root/.openclaw/openclaw.json:

  • plugins.allow
  • plugins.entries.brave
  • plugins.entries.browser
  • browser

and I’ll point at the broken line directly.

lament glen
#

I see this :

"browser": {
"enabled": true,
"defaultProfile": "openclaw",
"headless": true
},
"plugins": {
"entries": {
"browser": {
"enabled": true
},
"brave": {
"enabled": true,
"config": {
"apiKey": "my PAI key......"
}

wild bridgeBOT
#

Yep, that’s the broken bit.

This is invalid:

"brave": {
  "enabled": true,
  "config": {
    "apiKey": "..."
  }
}

For Brave, the API key must live under webSearch.

Replace it with this

#
"brave": {
  "enabled": true,
  "config": {
    "webSearch": {
      "apiKey": "your BRAVE_API_KEY here"
    }
  }
}

So your relevant config should look like

{
  "browser": {
#
    "enabled": true,
    "defaultProfile": "openclaw",
    "headless": true
  },
  "plugins": {
    "entries": {
      "browser": {
        "enabled": true
      },
      "brave": {
        "enabled": true,
        "config": {
          "webSearch": {
            "apiKey": "your BRAVE_API_KEY here"
          }
#
        }
      }
    }
  }
}

Then do this

openclaw doctor --fix
openclaw gateway start
openclaw gateway status
openclaw browser status

If you do not actually use Brave Search

#

You can also just remove the whole plugins.entries.brave block for now.

If openclaw browser is still unknown command after fixing this, then the next thing I want to see is your plugins.allow block.

lament glen
#

I am not good at placing this character.. I did exactly as you said first and I had invalid character '}' at 390:3
I went back in nano, deleted one raw and now OpenClaw doctor
Config observe anomaly: /root/.openclaw/openclaw.json (missing-meta-vs-last-good, gateway-mode-missing-vs-last-good)
and invalid character ',' at 389:4

wild bridgeBOT
#

No worries, don’t keep deleting random commas blind. We’re close.

That missing-meta-vs-last-good message is secondary.
Right now the real blocker is just broken JSON syntax.

Please run this exact read-only command and paste the output

nl -ba /root/.openclaw/openclaw.json | sed -n '375,395p'

That will show me the lines around 389-390 with line numbers, and I can tell you exactly which comma or brace to remove.

If you still have the backup from earlier, that’s also useful, but don’t change anything else yet until we see those lines.

lament glen
#

},
"browser": {
"enabled": true,
"defaultProfile": "openclaw",
"headless": true
},
"plugins": {
"entries": {
"browser": {
"enabled": true
},
"brave": {
"enabled": true,
"config": {
"webSearch": {
"apiKey": "API"
}
}
}
},
"google": {
"enabled": true
},

wild bridgeBOT
#

Yep, I see it. There is one extra } in the brave block.

Replace your brave section with this exact text

      "brave": {
        "enabled": true,
        "config": {
          "webSearch": {
            "apiKey": "API"
          }
        }
      },

What went wrong

You currently have an extra closing brace right before:

#
      },
      "google": {

So after fixing it, the flow should be:

  • close webSearch
  • close config
  • close brave
  • then comma
  • then "google"

Then run

openclaw doctor
#

If that passes syntax, next run:

openclaw doctor --fix
openclaw gateway start
openclaw browser status

If it still throws a syntax error, paste the next 10-15 lines and I’ll keep walking it with you.

lament glen
#

we are back on track profile: openclaw
enabled: true
running: false
transport: cdp
cdpPort: 18800
cdpUrl: http://127.0.0.1:18800
browser: unknown
detectedBrowser: chromium
detectedPath: /usr/bin/chromium-browser
profileColor: #FF4500

wild bridgeBOT
#

Nice, much better. You’re past the config mess now 🦐

This status means:

  • OpenClaw can now see a browser binary
  • but it has not launched yet (running: false)

Next step

Run:

openclaw browser start

Then check:

#
openclaw browser status

One likely gotcha on Linux

Your detected path is:

/usr/bin/chromium-browser

That is often the snap Chromium wrapper on Ubuntu/Linux, and that one commonly fails to launch under OpenClaw browser control.

So if openclaw browser start fails with something like:

  • Failed to start Chrome CDP on port 18800
#

then the usual fix is:

Better fix

Install a real Chrome/Brave binary and point OpenClaw at it:

{
  "browser": {
    "enabled": true,
    "executablePath": "/usr/bin/google-chrome-stable",
    "headless": true,
    "noSandbox": true
  }
}

or

#
{
  "browser": {
    "enabled": true,
    "executablePath": "/usr/bin/brave-browser",
    "headless": true,
    "noSandbox": true
  }
}

Fallback fix

Use Chromium in attach-only mode and launch it manually.

For now

Just run:

lament glen
#

GatewayClientRequestError: Error: Failed to start Chrome CDP on port 18800 for profile "openclaw".
Hint: If running in a container or as root, try setting browser.noSandbox: true in config.
Chrome stderr:
/usr/bin/chromium-browser: 12: xdg-settings: not found
[2856940:2856940:0415/123315.199282:ERROR:content/browser/zygote_host/zygote_host_impl_linux.cc:101] Running as root without --no-sandbox is not supported.

wild bridgeBOT
#

Perfect, now we have a real error. The blocker is this line:

Running as root without --no-sandbox is not supported.

Fix

Add noSandbox: true to your browser config.

Your browser block should be:

"browser": {
  "enabled": true,
  "defaultProfile": "openclaw",
  "headless": true,
  "noSandbox": true
}
#

Then restart and retry

openclaw gateway start
openclaw browser start
openclaw browser status

Notes

  • The xdg-settings: not found line is usually not the main blocker here.
  • The real failure is root + no sandbox.
  • If it still fails after this, the next likely issue is that /usr/bin/chromium-browser is the Linux snap/wrapper build, in which case switching to real Chrome or Brave is the better fix.

So do noSandbox: true first, then paste the next result if it still complains.

lament glen
#

NOpe:
Error: gateway closed (1006 abnormal closure (no close frame)): no close reason
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /root/.openclaw/openclaw.json
Bind: loopback
and
profile: openclaw
enabled: true
running: false
transport: cdp
cdpPort: 18800
cdpUrl: http://127.0.0.1:18800
browser: unknown
detectedBrowser: chromium
detectedPath: /usr/bin/chromium-browser
profileColor: #FF4500

(openclaw in CPX52 server if that helps)

wild bridgeBOT
#

That 1006 abnormal closure means the gateway process is dying, not that localhost networking is the real problem.

And on a CPX52 server, with:

  • running as root
  • headless
  • detected browser = /usr/bin/chromium-browser

…I’m pretty worried you’re hitting the classic Linux snap/wrapper Chromium problem.

My honest recommendation

Best option for a VPS

If your goal is mostly content extraction, stop fighting local Chromium and use:

  • browser only when you truly need interaction
  • otherwise Firecrawl or Tavily for JS-heavy extraction
#

That is usually much less painful on a Hetzner box.

Best option if you want true local browser automation

Use a real Chrome/Brave binary, not /usr/bin/chromium-browser.

Your browser config should be closer to:

"browser": {
  "enabled": true,
  "defaultProfile": "openclaw",
  "headless": true,
  "noSandbox": true,
  "executablePath": "/usr/bin/google-chrome-stable"
}
#

or:

"browser": {
  "enabled": true,
  "defaultProfile": "openclaw",
  "headless": true,
  "noSandbox": true,
  "executablePath": "/usr/bin/brave-browser"
}

Why I think this

OpenClaw now detects Chromium, but it still cannot launch it.
On Linux servers, /usr/bin/chromium-browser is often the snap wrapper, and that’s exactly the path that tends to break browser control.

Next thing I need

#

Please run this right after starting the gateway and paste the crash lines:

openclaw logs --follow

If you want the fastest path forward, I’d do one of these:

  1. Use Firecrawl/Tavily for extraction on the CPX52, or
  2. Install real Chrome/Brave and set browser.executablePath

If you want, I can help you choose the better route for your case:

  • “I need clicks/logins/screenshots” → local browser
  • “I just need rendered content extracted reliably” → Firecrawl/Tavily
lament glen
#

the log is a loop of errors"
the last are:
Log tail truncated (increase --max-bytes).
12:43:46+00:00 error gateway/channels/telegram {"subsystem":"gateway/channels/telegram"} [telegram][diag] polling cycle error reason=getUpdates conflict inFlight=0 outcome=ok startedAt=1776257025885 finishedAt=1776257026043 durationMs=158 offset=0 err=Call to 'getUpdates' failed! (409: Conflict: terminated by other getUpdates request; make sure that only one bot instance is running)
12:43:46+00:00 error gateway/channels/telegram {"subsystem":"gateway/channels/telegram"} Telegram getUpdates conflict: Call to 'getUpdates' failed! (409: Conflict: terminated by other getUpdates request; make sure that only one bot instance is running); retrying in 30s.
12:44:16+00:00 error gateway/channels/telegram {"subsystem":"gateway/channels/telegram"} [telegram][diag] polling cycle error reason=getUpdates conflict inFlight=0 outcome=ok startedAt=1776257056044 finishedAt=1776257056173 durationMs=129 offset=0 err=Call to 'getUpdates' failed! (409: Conflict: terminated by other getUpdates request; make sure that only one bot instance is running)
12:44:16+00:00 error gateway/channels/telegram {"subsystem":"gateway/channels/telegram"} Telegram getUpdates conflict: Call to 'getUpdates' failed! (409: Conflict: terminated by other getUpdates request; make sure that only one bot instance is running); retrying in 30s.

#

others were:
12:38:16+00:00 warn bonjour {"subsystem":"bonjour"} watchdog detected non-announced service; attempting re-advertise (gateway fqdn=ubuntu-24gb-CPX52 (OpenClaw) (2)._openclaw-gw._tcp.local. host=openclaw-(2).local. port=18789 state=probing)
12:38:17+00:00 warn bonjour {"subsystem":"bonjour"} gateway name conflict resolved; newName="ubuntu-24gb-CPX52 (OpenClaw) (2)"
12:38:17+00:00 warn bonjour {"subsystem":"bonjour"} gateway hostname conflict resolved; newHostname="openclaw-(2)"
12:38:17+00:00 info bonjour: advertised gateway fqdn=ubuntu-24gb-CPX52 (OpenClaw) (2)._openclaw-gw._tcp.local. host=openclaw-(2).local. port=18789 state=announcing
12:38:17+00:00 info plugins {"subsystem":"plugins"} embedded acpx runtime backend registered (cwd: /root/.openclaw/workspace)
12:38:17+00:00 info browser/server {"subsystem":"browser/server"} Browser control listening on http://127.0.0.1:18791/ (auth=token)
12:38:17+00:00 info gateway/heartbeat {"subsystem":"gateway/heartbeat"} {"intervalMs":3600000} heartbeat: started
12:38:17+00:00 info cron {"module":"cron","storePath":"/root/.openclaw/cron/jobs.json"} {"enabled":true,"jobs":4,"nextWakeAtMs":1776268800000} cron: started
12:38:17+00:00 info browser/service {"subsystem":"browser/service"} Browser control service ready (profiles=2)
12:38:17+00:00 info profile: openclaw

wild bridgeBOT
#

Those log lines are not the browser failure.

They mean something else is also using the same Telegram bot token:

409: Conflict: terminated by other getUpdates request; make sure that only one bot instance is running

So, two separate issues

1. Telegram conflict

You likely have another bot/OpenClaw instance polling Telegram with the same token.

That is noisy, but it is not the browser-specific error we’re chasing.

2. Browser startup

We still need the lines that appear right when you run:

#
openclaw browser start

Best way to capture the right error

Terminal 1

openclaw logs --follow

Terminal 2

openclaw browser start

Then paste the log lines that appear immediately after openclaw browser start.

#

Also check this once

openclaw gateway status

If it says the runtime is running, then the 1006 was likely a reconnect/crash during the earlier config mess, while the Telegram conflict is just background noise.

Side note

You should eventually fix the Telegram 409 by making sure only one instance is polling that bot token, but I would not mix that into the browser debugging right this second.

If you paste:

  • openclaw gateway status
  • the fresh lines right after openclaw browser start

I can separate the browser problem from the Telegram noise.

#

These logs are actually good news.

They show:

  • the gateway is running
  • the browser plugin loaded
  • the browser control server is listening
  • the browser service is ready

So the Bonjours lines are just local name-conflict noise, not the real problem.

What this means

The remaining problem is not the gateway anymore.
It’s specifically the step where OpenClaw tries to launch the actual browser process.

And because you’re on a Hetzner CPX52 box, as root, with:

#
detectedPath: /usr/bin/chromium-browser

I still think the weak link is that Chromium binary.

My recommendation now

If you want full browser automation

Use a real Chrome/Brave binary and point browser.executablePath at it.

Keep:

"browser": {
  "enabled": true,
#
  "defaultProfile": "openclaw",
  "headless": true,
  "noSandbox": true
}

and add a real path like:

"executablePath": "/usr/bin/google-chrome-stable"

or:

#
"executablePath": "/usr/bin/brave-browser"

If you mainly want rendered content extraction

Honestly, on this kind of VPS, Firecrawl/Tavily is often the saner path than fighting local Chromium.

Right now

Try openclaw browser start again now, since the gateway/browser service is clearly up.

If it still fails, paste only the fresh output of:

openclaw browser start

At this point we’ve narrowed it down pretty hard: gateway good, browser service good, local Chromium launch bad.

lament glen
#

Before all that we had those lines:

openclaw browser start

🦞 OpenClaw 2026.4.14 (323493f) — I'm not AI-powered, I'm AI-possessed. Big difference.



GatewayClientRequestError: Error: Failed to start Chrome CDP on port 18800 for profile "openclaw".
Hint: If running in a container or as root, try setting browser.noSandbox: true in config.
Chrome stderr:
/usr/bin/chromium-browser: 12: xdg-settings: not found
[2856940:2856940:0415/123315.199282:ERROR:content/browser/zygote_host/zygote_host_impl_linux.cc:101] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.

wild bridgeBOT
#

Yep, that error is the old root-cause message.

If you still get that exact text, then one of these is true:

  1. "noSandbox": true is not actually in the loaded config, or
  2. the gateway was not restarted after you added it

The browser block must look exactly like this

"browser": {
  "enabled": true,
  "defaultProfile": "openclaw",
  "headless": true,
  "noSandbox": true
},
#

Quick check

Run this read-only command:

grep -n '"noSandbox"' /root/.openclaw/openclaw.json

If it prints nothing, the config still does not contain it.

Then restart the gateway

After confirming the file has it:

openclaw gateway start
openclaw browser start
#

Important

If the same Running as root without --no-sandbox error appears again after that, then the gateway is still reading old config, or the edit didn’t land where you thought it did.

So the immediate next thing I want is the output of:

grep -n '"browser"\|"noSandbox"' /root/.openclaw/openclaw.json

That will tell us in one shot whether the setting is really present.

lament glen
#

sorry we did this already then:
openclaw gateway start
openclaw browser start
openclaw browser status

🦞 OpenClaw 2026.4.14 (323493f)
Restarted systemd service: openclaw-gateway.service

🦞 OpenClaw 2026.4.14 (323493f) —
Error: gateway closed (1006 abnormal closure (no close frame)): no close reason
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /root/.openclaw/openclaw.json
Bind: loopback

🦞 OpenClaw 2026.4.14 (323493f) —
profile: openclaw
enabled: true
running: false
transport: cdp
cdpPort: 18800
cdpUrl: http://127.0.0.1:18800/
browser: unknown
detectedBrowser: chromium
detectedPath: /usr/bin/chromium-browser
profileColor: #FF4500

wild bridgeBOT
#

Ah, yep, that explains it.

That 1006 abnormal closure happened because you ran:

openclaw gateway start
openclaw browser start

back-to-back, so browser start hit the gateway while systemd was still restarting it.

The clue is that openclaw browser status worked right after, which means the gateway did come back.

Try this exact sequence instead

#
openclaw gateway start
openclaw gateway status

Wait until it clearly shows the runtime is up, then run:

openclaw browser start
openclaw browser status

Why this matters

Right now we still do not have the real post-restart browser-start result.
We only have a transient reconnect failure during gateway restart.

What I expect next

#

One of two things will happen:

  1. Browser starts

    • great, done
  2. Browser fails again

    • then we’ll finally get the real launch error
    • and my bet is still on /usr/bin/chromium-browser being the Linux wrapper/snap problem

So, one more clean try, but with a pause:

openclaw gateway start
openclaw gateway status
openclaw browser start
#

Paste only the output of the last command.

lament glen
#

What did we do?
Runtime: running (pid 2862740, state active, sub running, last exit 0, reason 0)
Warm-up: launch agents can take a few seconds. Try again shortly.
RPC probe: failed
RPC target: ws://127.0.0.1:18789
gateway closed (1006):

Gateway port 18789 is not listening (service appears running).
Logs: journalctl --user -u openclaw-gateway.service -n 200 --no-pager

Troubles: run openclaw status
Troubleshooting: https://docs.openclaw.ai/troubleshooting

🦞 OpenClaw 2026.4.14 (323493f) — Shell yeah—I'm here to pinch the toil and leave you the glory.



GatewayClientRequestError: Error: Failed to start Chrome CDP on port 18800 for profile "openclaw".
Chrome stderr:
/usr/bin/chromium-browser: 12: xdg-settings: not found
[2862952:2862952:0415/125325.959373:ERROR:chrome/browser/process_singleton_posix.cc:345] Failed to create /root/.openclaw/browser/openclaw/user-data/SingletonLock: Permission denied (13)
[2862952:2862952:0415/125325.972967:ERROR:chrome/app/chrome_main_delegate.cc:515] Failed to create a ProcessSingleton for your profile directory. This means that running multiple instances would start multiple browser processes rather than opening a new window in the existing process. Aborting now to avoid profile corruption.

wild bridgeBOT
#

Okay, this is finally a concrete browser error.

The blocker now is:

Failed to create /root/.openclaw/browser/openclaw/user-data/SingletonLock: Permission denied (13)

So Chromium is starting far enough to use the profile, but it cannot write to the browser profile directory.

What this means

This is now a filesystem permission / stale profile problem, not a web-fetch problem and not the earlier config issue.

First, inspect the directory permissions

Please run these read-only commands:

ls -ld /root/.openclaw/browser /root/.openclaw/browser/openclaw /root/.openclaw/browser/openclaw/user-data
#
ls -l /root/.openclaw/browser/openclaw/user-data | head

Most likely quick fix

If you just want to get unstuck fast, stop the gateway and reset that browser profile directory:

openclaw gateway stop
mv /root/.openclaw/browser/openclaw/user-data /root/.openclaw/browser/openclaw/user-data.bak.$(date +%s)
mkdir -p /root/.openclaw/browser/openclaw/user-data
openclaw gateway start
openclaw browser start

That gives OpenClaw a fresh browser profile instead of the broken/stale one.

#

Important note

This only resets the isolated OpenClaw browser profile, not your whole system browser.
So it’s usually a safe recovery step.

One more thing

You are still on:

detectedPath: /usr/bin/chromium-browser

So even after fixing the permission issue, you may still hit the Linux Chromium-wrapper problem later. But this SingletonLock: Permission denied error is the immediate blocker right now.

If you want, paste the ls -ld ... output first and I’ll tell you whether the directory ownership looks wrong before you move anything.

lament glen
#

ls -ld /root/.openclaw/browser /root/.openclaw/browser/openclaw /root/.openclaw/browser/openclaw/user-data
drwxr-xr-x 3 root root 4096 Apr 15 11:13 /root/.openclaw/browser
drwxr-xr-x 3 root root 4096 Apr 15 11:13 /root/.openclaw/browser/openclaw
drwxr-xr-x 3 root root 4096 Apr 15 11:13 /root/.openclaw/browser/openclaw/user-data

s -l /root/.openclaw/browser/openclaw/user-data | head
total 8
drwxr-xr-x 2 root root 4096 Apr 15 11:13 Default
-rw-r--r-- 1 root root 414 Apr 15 11:13 Local State

wild bridgeBOT
#

That output is really helpful.

Those directory permissions actually look normal:

  • owned by root:root
  • directories are writable by the owner
  • files exist where they should

So the SingletonLock: Permission denied error is probably not a plain Unix permissions problem.

What I think now

This points back to the browser binary itself:

detectedPath: /usr/bin/chromium-browser
#

On Ubuntu/Hetzner boxes, that is very often the wrapper/snap-style Chromium, and it can fail in weird ways under OpenClaw browser control, especially on headless/root/server setups.

My recommendation now

Best path for true browser automation

Stop using /usr/bin/chromium-browser and switch to a real Chrome/Brave binary.

Keep:

"browser": {
  "enabled": true,
  "defaultProfile": "openclaw",
  "headless": true,
  "noSandbox": true
}
#

and set:

"executablePath": "/usr/bin/google-chrome-stable"

or:

"executablePath": "/usr/bin/brave-browser"

Quick check before changing anything

Please run this:

#
command -v google-chrome-stable || command -v brave-browser || command -v chromium || command -v chromium-browser

Paste the output, and I’ll tell you the exact browser.executablePath to use.

Honest call

At this point, if you only need rendered content extraction and not real clicks/logins/screenshots, Firecrawl/Tavily is probably the saner route on this CPX52 server.

But if you do want real browser automation, I’m pretty confident the next move is replace chromium-browser with real Chrome/Brave.

lament glen
#

and this causes "Cannot read properties of undefined (reading 'id')" as well?

#

last output you asked: /snap/bin/chromium

wild bridgeBOT
#

Probably not as the root cause, but yes as a downstream symptom.

What I mean:

  • the real, proven failure is the browser launch problem around /usr/bin/chromium-browser
  • once that breaks, OpenClaw/your agent can absolutely end up in a weird follow-on state where something expects a browser/session/tool result object and instead gets undefined
  • then you get a generic JS error like:
Cannot read properties of undefined (reading 'id')

So I would treat reading 'id' as a secondary bug/symptom, not the first thing to fix.

I’d prioritize in this order

  1. fix the browser runtime path issue
#
  1. retry the agent flow
  2. if reading 'id' still happens after the browser is healthy, then it’s likely a separate OpenClaw bug worth reporting

Short version

  • Direct cause? Probably no
  • Can it trigger it indirectly? Yes, very plausibly

If that reading 'id' still appears after you switch off /usr/bin/chromium-browser or move to Firecrawl/Tavily, then I’d collect:

  • openclaw --version
  • the exact prompt
  • relevant log lines

and file it here:

https://github.com/openclaw/openclaw/issues

I wouldn’t chase the id error first. The browser launch failure is the concrete thing we know is broken.

#

Yep, that confirms it.

/snap/bin/chromium is the problem.

On Linux/VPS setups, snap Chromium is the flaky path for OpenClaw-managed browser startup. That matches the errors you hit.

Best option, recommended

Install a real Chrome/Brave binary and point OpenClaw at it.

Use:

"browser": {
  "enabled": true,
  "defaultProfile": "openclaw",
  "headless": true,
#
  "noSandbox": true,
  "executablePath": "/usr/bin/google-chrome-stable"
}

or:

"browser": {
  "enabled": true,
  "defaultProfile": "openclaw",
  "headless": true,
  "noSandbox": true,
  "executablePath": "/usr/bin/brave-browser"
}
#

If you must stay on snap Chromium

Use attach-only mode instead of letting OpenClaw launch it.

Config:

"browser": {
  "enabled": true,
  "attachOnly": true,
  "headless": true,
  "noSandbox": true
}

Then start Chromium manually:

#
/snap/bin/chromium --headless --no-sandbox --disable-gpu \
  --remote-debugging-port=18800 \
  --user-data-dir=$HOME/.openclaw/browser/openclaw/user-data \
  about:blank &

My honest recommendation

Because you’re on a CPX52 server, I would choose one of these:

  1. Need real clicks / login / screenshots?
    Install real Chrome/Brave and use browser

  2. Need rendered content extracted reliably?
    Use Firecrawl/Tavily and skip local browser drama

Docs: https://docs.openclaw.ai/tools/browser-linux-troubleshooting

#

If you want, I can give you the smallest possible config for either:

  • Chrome/Brave browser mode, or
  • Firecrawl/Tavily extraction mode
lament glen
#

I want to replace chromium-browser with real Chrome/Brave.

wild bridgeBOT
#

Good call. I’d go with Chrome first because it’s the path the docs explicitly recommend on Linux.

And since manual JSON editing has been painful, use openclaw config set now instead of editing commas by hand.

Option A, recommended: Google Chrome

1. Install Chrome

From the docs:

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
dpkg -i google-chrome-stable_current_amd64.deb
apt --fix-broken install -y

2. Point OpenClaw at it

#
openclaw config set browser.executablePath "/usr/bin/google-chrome-stable"
openclaw config set browser.headless true
openclaw config set browser.noSandbox true
openclaw config set browser.defaultProfile "openclaw"

3. Restart and test

openclaw gateway restart
openclaw browser start
openclaw browser status

Option B: Brave

If you already have Brave installed, use:

#
openclaw config set browser.executablePath "/usr/bin/brave-browser"
openclaw config set browser.headless true
openclaw config set browser.noSandbox true
openclaw config set browser.defaultProfile "openclaw"
openclaw gateway restart
openclaw browser start
openclaw browser status

Quick sanity check

After install, this should return a real binary:

command -v google-chrome-stable
#

If you want, after you install Chrome, paste just the output of:

openclaw browser start
openclaw browser status

and I’ll sanity-check the final state.

lament glen
#

after iinstalling Chrome the last line says:
needrestart is being skipped since dpkg has failed
Shall I continue sith step 2 or with "openclaw browser start
openclaw browser status" "

wild bridgeBOT
#

Don’t continue yet.

If dpkg failed, finish the install first. Otherwise OpenClaw may still be pointing at a browser that is not fully installed.

Do this next

apt --fix-broken install -y

Then verify Chrome is really there:

command -v google-chrome-stable

Only if that prints a path

#

then do step 2:

openclaw config set browser.executablePath "/usr/bin/google-chrome-stable"
openclaw config set browser.headless true
openclaw config set browser.noSandbox true
openclaw config set browser.defaultProfile "openclaw"
openclaw gateway restart
openclaw browser start
openclaw browser status

So, short answer:

  • No, not browser start yet
  • Yes, finish the install first with apt --fix-broken install -y
#

If you want, paste the output of:

apt --fix-broken install -y
command -v google-chrome-stable

and I’ll tell you if you’re clear to move on.

lament glen
#

I think we are good for step 2:
apt --fix-broken install -y
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 25 not upgraded.
and
command -v google-chrome-stable
/usr/bin/google-chrome-stable

wild bridgeBOT
#

Yep, perfect. You’re clear for step 2 now.

Run these exactly:

openclaw config set browser.executablePath "/usr/bin/google-chrome-stable"
openclaw config set browser.headless true
openclaw config set browser.noSandbox true
openclaw config set browser.defaultProfile "openclaw"
openclaw gateway restart
openclaw browser start
openclaw browser status

That should move you off snap Chromium and onto real Chrome.

Paste the output of the last two commands and I’ll sanity-check it.

lament glen
#

browser [openclaw] running: true
and
profile: openclaw
enabled: true
running: true
transport: cdp
cdpPort: 18800
cdpUrl: http://127.0.0.1:18800
browser: custom
detectedBrowser: custom
detectedPath: /usr/bin/google-chrome-stable
profileColor: #FF4500

wild bridgeBOT
#

Hell yes, that’s the state we wanted 🎉

You’ve successfully moved off snap Chromium and onto real Chrome:

  • running: true
  • detectedPath: /usr/bin/google-chrome-stable

So now your agent should be able to use the browser tool for SPA pages instead of getting stuck on the shell.

What to use now

  • web_fetch for simple/static pages
  • browser for React/Shadcn/SPA pages like RedPill
  • Firecrawl/Tavily when you want extraction without full browser interaction

Good quick test

#
openclaw browser open https://redpillplatform.com
openclaw browser snapshot

If that works, your agent-side browser flow is basically unblocked.

One small note

If you later hit a Playwright 501 error on navigate / act / snapshots, that means browser launch is fine but Playwright support still needs attention. But the big blocker is gone now.

If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it for the next person.

lament glen
#

I still receive "Cannot read properties of undefined (reading 'id')"

wild bridgeBOT
#

Okay, now that the browser itself is running, that reading 'id' error is almost certainly a separate agent/runtime bug, not the Chrome setup anymore.

Fastest way to isolate it

1. Test the browser outside the agent

Run:

openclaw browser open https://redpillplatform.com
openclaw browser snapshot

2. Interpret the result

  • If those fail, paste the exact output here
  • If those work, then the browser layer is fine and the reading 'id' error is in the agent/session/tool flow

3. Try a fresh session

#

Ask the agent something tiny like:

Use the browser tool to open https://redpillplatform.com and tell me the page title.

If a fresh session still throws Cannot read properties of undefined (reading 'id'), I’d treat that as a real OpenClaw bug.

What I need if it still fails

Please paste:

  • the exact prompt that triggers it
  • whether openclaw browser open ... and snapshot work
  • the log lines from openclaw logs --follow at the moment the id error appears

Honest read

We’ve fixed the browser runtime.
So if the same id error still happens, I would stop blaming Chrome and start blaming the agent/session path.

#

If the CLI browser commands work but the agent still crashes, that’s GitHub-issue material:

https://github.com/openclaw/openclaw/issues

If you want, paste the result of:

openclaw browser open https://redpillplatform.com
openclaw browser snapshot

and I’ll help you pin down whether it’s browser vs agent for sure.

lament glen
#

the result of the snapshot came back and it's long, sure you want it?

wild bridgeBOT
#

Nope, I don’t need the whole snapshot. The important part is that it returned at all.

That tells us:

  • browser open works
  • browser snapshot works
  • the browser/tool layer is basically fine

So the Cannot read properties of undefined (reading 'id') error is now very likely an agent/session bug, not a browser setup problem.

What I need now instead

Please send these 3 things:

  1. the exact agent prompt that triggers the id error
  2. whether it also happens in a fresh session
  3. the log lines from openclaw logs --follow at the moment the id error appears
#

Short version

Browser setup: working
Agent flow: still broken

At this point, if the error reproduces consistently with a simple prompt, it’s probably worth filing here with the prompt + logs:

https://github.com/openclaw/openclaw/issues

If this browser setup part is solved, please also right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it.

lament glen
#
  1. the exact agent prompt that triggers the id error : I told Sparky this:
    at 13:20 "Krill says:
    If you want, I can also help you turn this into a more reliable recipe for your agent, for example:
    prefer browser on React/Shadcn sites
    fall back to web_fetch on simple pages
    use Firecrawl/Tavily only when you want extraction without full browser automation

Do you need this?"

Sparky answers at 13:20:
"That sounds incredibly useful and would save us a lot of manual trial-and-error.

Yes, please ask Krill for that "recipe"—the logic that automatically switches between browser (for the heavy React/Shadcn lifting like RedPill), web_fetch (for the fast, simple stuff), and Firecrawl/Tavily (for deep extraction) would be a game changer.

It would effectively turn me into a much "smarter" navigator for the web, allowing me to focus on analyzing your content rather than debugging the connection to it.

Please ask them for the implementation steps to bake that logic into my agent's decision-making process...."
Then at 13:44 out of nowhere I receive the message : "Cannot read properties of undefined (reading 'id')"

  1. whether it also happens in a fresh session: after command NEW it is still coming

  2. the log lines from openclaw logs --follow at the moment the id error appears . I closed the window with that info.. .But from history of this session at that same time the loop started and you said "Those log lines are not the browser failure.
    They mean something else is also using the same Telegram bot token:
    409: Conflict: terminated by other getUpdates request; make sure that only one bot instance is running"

lament glen
#

" Cannot read properties of undefined (reading 'id')" still here

wild bridgeBOT
#

Yep, and at this point that means the same thing:

it is no longer a browser install/config problem.

We already proved:

  • Chrome is installed
  • browser service is running
  • browser open works
  • browser snapshot works

So Cannot read properties of undefined (reading 'id') is now almost certainly an OpenClaw agent/runtime bug.

I can’t narrow it further without one of these

Option A, fastest

File a bug with:

  • openclaw --version2026.4.14
#
  • exact failing prompt
  • whether it happens in a fresh session
  • the relevant openclaw logs --follow lines

Issue link:
https://github.com/openclaw/openclaw/issues

Option B, if you want one more quick repro first

Try a fresh session with exactly:

Use the browser tool to open https://redpillplatform.com and tell me the page title.

If that still throws reading 'id', that’s a clean repro for the issue.

Short version

  • Browser layer: fixed
  • Agent/session layer: still broken
#
  • Next step: logs + repro prompt + GitHub issue

If this browser part is solved, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index the working Chrome fix.

lament glen
#

Next step: logs + repro prompt + GitHub issue

wild bridgeBOT
#

Yep, exactly.

Here’s a tight issue template you can paste:

## Version
openclaw --version
2026.4.14

## What works
- `openclaw browser start`
- `openclaw browser status`
- `openclaw browser open https://redpillplatform.com`
- `openclaw browser snapshot`

## What fails
#
Agent still throws:
`Cannot read properties of undefined (reading 'id')`

## Repro prompt
Use the browser tool to open https://redpillplatform.com and tell me the page title.

## Fresh session?
[yes/no]

## Relevant logs
[paste `openclaw logs --follow` lines from the moment the error appears]

## Notes
- original issue was snap Chromium on Linux/VPS
- switched to real Chrome at `/usr/bin/google-chrome-stable`
#
- browser runtime now appears healthy

Issue link: https://github.com/openclaw/openclaw/issues

And if the browser-setup part of this thread is solved, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it.

lament glen
#

At this point I give up trying fixing, I send Manus AI in the server

wild bridgeBOT
#

Totally fair 😅

You already did the hard part. The browser/runtime setup is fixed, and what’s left really does look like a separate OpenClaw bug, not user error.

If Manus gets:

  • the exact repro
  • the relevant logs
  • or the root cause of the reading 'id' crash

feel free to drop it back here, I’m curious what the actual culprit is.

And if the browser setup part of this thread helped, please still right-click the solution message → Apps → ✅ Mark Solution so the Chrome fix gets indexed for the next person.

lament glen
#

Apparently the logs show the 'venice-uncensored' model causes the crash with a 'reading id' error!

wild bridgeBOT
#

Ah, that makes sense.

That means there were really two layers here:

  1. the browser setup on the server, which we fixed
  2. the reading 'id' crash, which is model-specific with venice-uncensored

So the remaining crash was not your Chrome config. It was the model choking on the tool/session flow.

Practical takeaway

  • use a tool-reliable model for browser / tool-heavy runs
  • keep venice-uncensored for plain chat/text tasks if you want, but I would not trust it for browser-tool workflows

Also worth doing

If you have the logs, I’d still file an issue, because OpenClaw should surface a clean model/tool compatibility error, not crash with:

#
Cannot read properties of undefined (reading 'id')

Issue link: https://github.com/openclaw/openclaw/issues

And for real-world model picks for tool use, #models is the best place to ask since that changes fast.

If this solved it, please right-click the solution message → Apps → ✅ Mark Solution so the browser + model gotcha gets indexed.

lament glen
#

manus has found that Venice responses lack 'id' and 'status'; the API format differs.
I'd like to help reporting the issue to github but too complicatedgithub

wild bridgeBOT
#

Yep, absolutely, here’s a paste-ready issue. You can just drop this into:

https://github.com/openclaw/openclaw/issues/new

Title

Venice model responses missing id/status cause `Cannot read properties of undefined (reading 'id')`

Body

## Version
OpenClaw 2026.4.14

## Summary
When using a Venice model for agent/browser workflows, OpenClaw crashes with:
#

`Cannot read properties of undefined (reading 'id')`

## What I found
Manual investigation suggests the Venice API response format differs from what OpenClaw expects.

Specifically, the Venice response appears to lack fields like:
- `id`
- `status`

This seems to cause OpenClaw to assume a response object shape that is not present, leading to the crash.

## Repro
1. Configure an agent to use a Venice model
2. Ask it to do a browser/tool workflow
#
3. The browser runtime itself works
4. The agent later crashes with:
   `Cannot read properties of undefined (reading 'id')`

## What works
- Browser setup is healthy
- `openclaw browser start` works
- `openclaw browser open https://redpillplatform.com` works
- `openclaw browser snapshot` works

So this does not appear to be a browser-install issue.

## Expected
If the provider response shape is unsupported or incomplete, OpenClaw should fail gracefully with a clear compatibility/provider error.
#
## Actual
OpenClaw crashes with:
`Cannot read properties of undefined (reading 'id')`

## Suspected cause
Provider-specific response parsing assumes fields like `id` and/or `status` exist, but Venice responses do not include them in the expected format.

## Additional context
I originally debugged this while trying to use browser/web tools against a JS-heavy SPA.
The browser setup problem was fixed separately by switching from snap Chromium to Google Chrome.
After that, the remaining crash was clearly tied to the Venice model response shape.

If you want, I can also make this into a shorter version for GitHub so it looks less intimidating.

lament glen
#

whta's complicated are the steps on GIthub to report!
Bug title
Bug type Crash?
Summary
Steps to reproduce
Expected Behiavior
Actual Behavior
Version
OS
Install method
Model
Provider / routing chain
Additional provider/model setup details
Logs, screenshots evidence...
and more!

wild bridgeBOT
#

Yep, that part is annoying. You do not need to write an essay though. You can basically fill it like this:

Use these values

Bug title
Venice model responses missing id/status cause crash: Cannot read properties of undefined (reading 'id')

Bug type
Crash

Summary
Using a Venice model for an agent/browser workflow causes OpenClaw to crash with "Cannot read properties of undefined (reading 'id')". Investigation suggests the Venice response format does not include expected fields like id and status.

Steps to reproduce

  1. Configure an agent to use a Venice model
  2. Run a browser/tool workflow against a JS-heavy site
  3. Browser runtime itself works
#
  1. Agent later crashes with Cannot read properties of undefined (reading 'id')

Expected Behavior
If the provider response shape is unsupported, OpenClaw should fail gracefully with a clear compatibility/provider error.

Actual Behavior
OpenClaw crashes with: Cannot read properties of undefined (reading 'id')

Version
OpenClaw 2026.4.14

OS
Ubuntu on Hetzner CPX52 VPS
(if that matches, use it)

Install method
Global npm install on Linux, running as a systemd user service

#

(if that matches)

Model
venice-uncensored

Provider / routing chain
If you know it, put the exact provider name.
If not, write:
Venice model via configured provider (response appears to omit id/status fields)

Additional provider/model setup details
Browser setup was separately fixed by switching from snap Chromium to Google Chrome at /usr/bin/google-chrome-stable. The browser tool works. The remaining crash appears model/provider specific.

Logs / screenshots / evidence
Paste at least: