#lobster and llm task
1 messages · Page 1 of 1 (latest)
Yep — but there’s an important gotcha here: llm-task from a .lobster workflow only works reliably today with the standalone Lobster CLI + openclaw.invoke configured with gateway/auth context. The bundled embedded Lobster runner inside OpenClaw does not reliably inherit that context for nested openclaw.invoke calls yet, so examples using this inside embedded Lobster can look correct and still fail.
Minimal config pieces:
{
"plugins": {
"entries": {
"llm-task": { "enabled": true }
}
},
"tools": {
"alsoAllow": ["lobster", "llm-task"]
}
}
Standalone .lobster example:
openclaw.invoke --tool llm-task --action json --args-json '{
"prompt": "Classify this message. Return only JSON matching the schema.",
"thinking": "low",
"input": {
"message": "Can you help me install OpenClaw on Ubuntu?"
},
"schema": {
"type": "object",
"properties": {
"category": { "type": "string" },
"summary": { "type": "string" }
},
"required": ["category", "summary"],
"additionalProperties": false
}
}'
If you’re running this through the OpenClaw embedded lobster tool, the current recommendation is: call llm-task directly outside Lobster, or keep Lobster steps to normal CLI/script commands until the embedded bridge lands.
Docs:
https://docs.openclaw.ai/tools/lobster
https://docs.openclaw.ai/tools/llm-task
If you paste your openclaw --version plus the exact error/output, I can sanity-check whether you’re hitting this limitation or a config/auth issue. And for “has anyone personally got this working?” style examples, #users-helping-users is also a good place for human war stories.
I've tried running your example but I got this error message back from openclaw
- The .lobster file isn't a valid YAML workflow. The lobster CLI's run command expects YAML workflow files (with name, steps, etc.), but this file is a raw shell-style pipeline (openclaw.invoke --tool llm-task ...). That's why lobster run choked with:
Error: Implicit keys need to be on a single line at line 1, column 1
2. Even when I ran the pipeline directly as a string (bypassing the file format issue), the openclaw.invoke call itself failed with a 500 error — tool execution failed. This means the lobster CLI's openclaw.invoke integration isn't working in this environment (likely missing CLAWD_URL/CLAWD_TOKEN env vars or the invoke handler isn't wired up in this lobster build).
Bottom line: The file content is fine as a pipeline concept, but it can't run as-is because (a) lobster run doesn't accept raw pipeline syntax in .lobster files, and (b) the openclaw.invoke tool isn't functional in this lobster installation.
Yep — you caught a real mismatch there. My example mixed two Lobster modes, sorry about that.
The split is:
lobster run some-file.lobsterexpects a YAML/JSON workflow file, like:
name: llm-task-test
steps:
- id: classify
command: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return { ok: true } as JSON","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
- The raw pipeline form:
openclaw.invoke --tool llm-task --action json --args-json '{...}'
is meant to be passed as the pipeline string to the OpenClaw lobster tool, not saved directly as a .lobster workflow file and run as YAML.
For the 500: most likely one of these is missing:
{
"plugins": {
"entries": {
"llm-task": { "enabled": true }
}
},
"tools": {
"alsoAllow": ["lobster", "llm-task"]
}
}
If you’re using the standalone Lobster CLI, then yeah, openclaw.invoke also needs to know how to reach your running OpenClaw gateway — so gateway URL/token/env wiring can matter there. The embedded OpenClaw Lobster tool path is the cleaner route.
Can you paste openclaw --version and the relevant redacted bit from openclaw status --all? That’ll tell us whether this is config/tool enablement vs a Lobster build/runtime mismatch.
Docs for reference: https://docs.openclaw.ai/tools/lobster and https://docs.openclaw.ai/tools/llm-task
openclaw --version returns OpenClaw 2026.5.7 (eeef486)
How should I pass this pipeline to openclaw
For OpenClaw, don’t pass it to the standalone lobster run CLI. Pass it to the OpenClaw agent, and have the agent call the lobster tool with the pipeline string.
From terminal, the shape is:
openclaw agent --message "Run the lobster tool with action=run, timeoutMs=30000, and this pipeline:
openclaw.invoke --tool llm-task --action json --args-json '{...}'
"
More reliable quoting version:
cat > /tmp/lobster-prompt.txt <<'EOF'
Run the lobster tool with this payload:
{
"action": "run",
"timeoutMs": 30000,
"pipeline": "openclaw.invoke --tool llm-task --action json --args-json '{\"prompt\":\"Return JSON with ok=true\",\"schema\":{\"type\":\"object\",\"properties\":{\"ok\":{\"type\":\"boolean\"}},\"required\":[\"ok\"],\"additionalProperties\":false}}'"
}
EOF
openclaw agent --message "$(cat /tmp/lobster-prompt.txt)"
Same thing in Control UI / chat: paste the JSON payload and say “run this with the lobster tool.” The important bit is that pipeline is a string field on the OpenClaw lobster tool call.
Also make sure both tools are enabled/allowed:
{
"plugins": {
"entries": {
"llm-task": { "enabled": true }
}
},
"tools": {
"alsoAllow": ["lobster", "llm-task"]
}
}
If you still get the 500 after that, check openclaw logs --follow while running it — the gateway log should show whether llm-task is missing, blocked by tool allowlist, or failing model/auth resolution.
Docs: https://docs.openclaw.ai/tools/lobster / https://docs.openclaw.ai/tools/llm-task
I have those entries in openclaw.json. I also have the script saved in a file, so how would I prompt openclaw to execute that file?
If the file is a YAML/JSON Lobster workflow file (name:, steps:, etc.), prompt OpenClaw like this:
openclaw agent --message 'Use the lobster tool to run this workflow file:
{
"action": "run",
"pipeline": "/absolute/path/to/your-workflow.lobster",
"timeoutMs": 30000
}'
If the workflow file needs args:
openclaw agent --message 'Use the lobster tool to run this workflow file:
{
"action": "run",
"pipeline": "/absolute/path/to/your-workflow.lobster",
"argsJson": "{\"tag\":\"family\"}",
"timeoutMs": 30000
}'
Important: that file path must be readable from the machine running the OpenClaw gateway, not just your terminal.
If the file is still a raw pipeline script like:
openclaw.invoke --tool llm-task --action json --args-json '{...}'
then don’t pass the filename as pipeline; pass the file contents as the pipeline string:
openclaw agent --message "Use the lobster tool with action=run, timeoutMs=30000, and pipeline set to this exact pipeline:
$(cat /absolute/path/to/pipeline.lobster)
"
My recommendation: convert it to the YAML workflow-file form if you want to keep it on disk and run it by path. Use raw pipeline strings for quick one-offs.
How would I run this if I can only use telegram to communicate?
If Telegram is your only interface, you run it by messaging your OpenClaw Telegram bot/agent directly. No terminal needed.
Send a Telegram message like:
Run the lobster tool with this payload:
{
"action": "run",
"pipeline": "/absolute/path/on-the-gateway/your-workflow.lobster",
"timeoutMs": 30000
}
If it needs args:
Run the lobster tool with this payload:
{
"action": "run",
"pipeline": "/absolute/path/on-the-gateway/your-workflow.lobster",
"argsJson": "{\"tag\":\"family\"}",
"timeoutMs": 30000
}
Two important gotchas:
- The file path has to exist on the machine running the OpenClaw gateway. Your phone/Telegram attachment path won’t count unless you’ve saved it onto that machine.
- If your saved file is a raw pipeline, not YAML workflow format, paste/send the pipeline contents instead and say:
Run the lobster tool with action=run, timeoutMs=30000, and pipeline set to this exact text:
openclaw.invoke --tool llm-task --action json --args-json '...'
So the clean Telegram-only workflow is: save the .lobster YAML workflow on the gateway box once, then trigger it from Telegram by asking OpenClaw to run the lobster tool with pipeline set to that absolute path.
I tried that and get this message
The lobster CLI can't run this pipeline. Here's why:
openclaw.invoke is not a lobster command. The lobster CLI (node /home/admin/tools/lobster/bin/lobster.js) is a standalone Node.js tool that only understands its own pipeline syntax (exec, where, pick, approve, etc.). It has no built-in integration with OpenClaw's tool system.
The openclaw.invoke syntax only works when lobster is embedded inside an OpenClaw agent session (like the one I'm running in right now), not when invoked directly from the shell.
To make this work, you'd need to either:
- Run it as an OpenClaw agent task (which is what I did earlier with llm_task — that worked because I'm inside the OpenClaw runtime)
- Wrap it in a shell script that uses openclaw CLI commands instead of lobster's openclaw.invoke
- Use lobster's exec to call the OpenClaw CLI from within a lobster pipeline
That error means the agent is still taking the wrong route: it’s invoking the standalone Lobster CLI (node /home/admin/tools/lobster/bin/lobster.js) instead of calling the OpenClaw lobster tool.
From Telegram, try being extremely explicit:
Do not use exec, shell, terminal, node, or the standalone lobster CLI.
Call the OpenClaw agent tool named `lobster` directly.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/absolute/path/on-the-gateway/your-workflow.lobster",
"timeoutMs": 30000
}
If the `lobster` tool is not available to you, stop and say: "lobster tool unavailable".
If your saved file is a raw pipeline containing openclaw.invoke ..., don’t pass the path. Send:
Do not use exec, shell, terminal, node, or the standalone lobster CLI.
Call the OpenClaw agent tool named `lobster` directly with action=run.
Use this as the pipeline string:
openclaw.invoke --tool llm-task --action json --args-json '...'
If it still says “lobster CLI can’t run this,” then the Telegram-facing agent likely does not actually have the lobster tool exposed, even if your config has the entries. Common causes:
- config changed but gateway wasn’t restarted
tools.alsoAllowwas added under a different agent than the one Telegram routes to- a restrictive
tools.allowis overriding/limiting tools - the lobster plugin isn’t installed/loaded for that runtime
Quick checks on the gateway box:
openclaw plugins list | grep lobster
openclaw plugins doctor
openclaw status --all
openclaw logs --follow
The key phrase is: call the OpenClaw lobster tool directly. Anything involving lobster run, node .../lobster.js, or shell execution is the standalone CLI path, and openclaw.invoke won’t work there.
I get the message lobster tool unavailable
That confirms it: your Telegram-routed agent cannot see the embedded lobster tool. So the prompt is fine now — the tool exposure isn’t.
Fix checklist:
- Verify the plugin is installed/loaded on the gateway:
openclaw plugins list | grep lobster
openclaw plugins doctor
If it’s not installed, install/enable it:
openclaw plugins install @openclaw/lobster
openclaw plugins enable lobster
- Make sure the Telegram agent specifically allows it. If your Telegram route uses a non-
mainagent, roottools.alsoAllowmay not be enough depending on overrides. Add it to that agent too:
{
tools: {
alsoAllow: ["lobster", "llm-task"]
},
agents: {
list: [
{
id: "YOUR_TELEGRAM_AGENT_ID",
tools: {
alsoAllow: ["lobster", "llm-task"]
}
}
]
}
}
-
If that agent has
tools.profile: "messaging"or"minimal", that’s probably the culprit. Those profiles are intentionally narrow; either addalsoAllowas above or switch totools.profile: "full"for that agent if you trust the surface. -
Restart/reload the gateway after config/plugin changes:
openclaw gateway restart
Then from Telegram send the same explicit prompt again:
Do not use shell or the standalone lobster CLI. Call the OpenClaw tool named lobster directly. If unavailable, say so.
Payload:
{
"action": "run",
"pipeline": "/absolute/path/on-the-gateway/your-workflow.lobster",
"timeoutMs": 30000
}
If it still says unavailable after restart, paste the redacted agents.list entry for the Telegram agent and the output of openclaw plugins list | grep lobster.
This is my config
{
"id": "lead-scout",
"name": "DBA Lead Scout",
"workspace": "~/.openclaw/workspace-dba-scout",
"model": "lmstudio/qwen/qwen3.6-35b-a3b",
"params": {
"temperature": 0.1
},
"tools": {
"allow": [
"*"
],
"deny": [
"web-search"
]
}
},
That agent config isn’t the part that enables Lobster. tools.allow: ["*"] means “allow all tools that are already loaded/available” — it does not make optional plugin tools load by itself.
Two things I’d change/check:
- Your deny entry is the wrong tool name:
"deny": ["web_search"]
not web-search. Not the Lobster issue, but worth fixing.
- You need the Lobster plugin loaded globally, and not blocked by
plugins.allow.
At top-level config, you want something like:
{
plugins: {
entries: {
lobster: { enabled: true },
"llm-task": { enabled: true }
}
// If you have plugins.allow set, it MUST include both:
// allow: ["lobster", "llm-task", ...]
},
agents: {
list: [
{
id: "lead-scout",
name: "DBA Lead Scout",
workspace: "~/.openclaw/workspace-dba-scout",
model: "lmstudio/qwen/qwen3.6-35b-a3b",
params: { temperature: 0.1 },
tools: {
allow: ["*"],
deny: ["web_search"]
}
}
]
}
}
Then restart the gateway:
openclaw gateway restart
If you’re on the gateway box, run:
openclaw plugins list | grep -E 'lobster|llm-task'
openclaw plugins doctor
openclaw doctor
If plugins.allow exists anywhere in your config and does not include lobster, that’s the most likely reason the tool says unavailable. tools.allow: ["*"] won’t bypass plugins.allow.
One more caveat: Qwen via LM Studio may be shaky at tool calling. Once Lobster appears in the tool list, if the agent still tries shell/CLI instead of the tool, test once with a tool-reliable cloud model to separate “tool not exposed” from “model chose the wrong tool path.”
ah ok, so the lobster plugin was not installed. I installed it and I ran the prompt again and got a different error
The lobster tool is available, but it doesn't support running .lobster workflow files directly — it only accepts inline pipeline command strings. The file examples/simple-llm-example.lobster is a workflow file (not an inline pipeline), so the tool can't execute it.
Nice, progress. That new error sounds like either the installed @openclaw/lobster plugin is older than the OpenClaw docs, or the model is paraphrasing the tool schema incorrectly.
The current docs say the embedded Lobster tool should accept workflow file paths as pipeline:
{
"action": "run",
"pipeline": "/path/to/inbox-triage.lobster",
"argsJson": "{\"tag\":\"family\"}"
}
So I’d check/update the plugin first:
openclaw plugins list | grep lobster
openclaw plugins update
openclaw plugins doctor
openclaw gateway restart
Then try again from Telegram with an absolute path:
Call the OpenClaw tool named lobster directly. Do not use shell/exec/CLI.
Use payload:
{
"action": "run",
"pipeline": "/home/admin/path/to/examples/simple-llm-example.lobster",
"timeoutMs": 30000
}
If it still says file workflows aren’t supported, use the workaround: paste the inline pipeline contents as the pipeline string instead of the filename.
For your example, that means something like:
Call the OpenClaw tool named lobster directly with action=run.
Use this inline pipeline string:
openclaw.invoke --tool llm-task --action json --args-json '...'
But I’d treat “doesn’t support workflow files” as suspicious, because the docs for 2026.5.7 say it does. If plugin update doesn’t fix it, this is probably worth a GitHub issue with openclaw --version, openclaw plugins list, and the exact tool error: https://github.com/openclaw/openclaw/issues
Can you give me the prompt in full
Yep — here’s the full Telegram prompt I’d send.
Replace the path with the real absolute path on your gateway machine:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/home/admin/examples/simple-llm-example.lobster",
"timeoutMs": 30000,
"maxStdoutBytes": 512000
}
If the `lobster` tool reports that workflow files are not supported, stop and tell me the exact error. Do not try to work around it by using shell or the standalone Lobster CLI.
If that still gives the “workflow files not supported” error, use this version instead, but replace the pipeline line with the actual raw pipeline text from your file:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.
Use this exact tool payload:
{
"action": "run",
"pipeline": "openclaw.invoke --tool llm-task --action json --args-json '{\"prompt\":\"Return JSON with ok=true\",\"schema\":{\"type\":\"object\",\"properties\":{\"ok\":{\"type\":\"boolean\"}},\"required\":[\"ok\"],\"additionalProperties\":false}}'",
"timeoutMs": 30000,
"maxStdoutBytes": 512000
}
The first prompt is the intended file-based path. The second is the inline-pipeline fallback.
ok, the prompt worked
Awesome — glad we got it unstuck 🎉
So the final path was: install/enable the Lobster plugin, then explicitly prompt Telegram/OpenClaw to call the embedded lobster tool directly instead of the standalone CLI.
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes it for the next person who hits this.
I still can't quite get the file to work, can you give me another example of a lobster file and the prompt I need to execute it
Yep. Here’s a clean workflow-file example you can save as a real .lobster YAML file.
Save this on the gateway machine as:
/home/admin/examples/simple-llm-workflow.lobster
File contents:
name: simple-llm-workflow
steps:
- id: ask_llm
command: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this lead. Return JSON only with company, fit, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"reason":{"type":"string"}},"required":["company","fit","reason"],"additionalProperties":false}}'
Then from Telegram, send this exact prompt:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/home/admin/examples/simple-llm-workflow.lobster",
"timeoutMs": 30000,
"maxStdoutBytes": 512000
}
If this fails, tell me the exact lobster tool error. Do not try to work around it with shell or the standalone Lobster CLI.
If that still says file workflows are unsupported, then your installed Lobster plugin likely only supports inline pipelines. In that case, send this Telegram prompt instead:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.
Use this exact tool payload:
{
"action": "run",
"pipeline": "openclaw.invoke --tool llm-task --action json --args-json '{\"prompt\":\"Classify this lead. Return JSON only with company, fit, and reason.\",\"thinking\":\"low\",\"input\":{\"company\":\"Acme Dental\",\"notes\":\"Multi-location dental practice looking for help with missed-call followup and appointment reminders.\"},\"schema\":{\"type\":\"object\",\"properties\":{\"company\":{\"type\":\"string\"},\"fit\":{\"type\":\"string\",\"enum\":[\"high\",\"medium\",\"low\"]},\"reason\":{\"type\":\"string\"}},\"required\":[\"company\",\"fit\",\"reason\"],\"additionalProperties\":false}}'",
"timeoutMs": 30000,
"maxStdoutBytes": 512000
}
The first one tests file execution. The second is the same workflow as an inline pipeline, which is the fallback if your plugin build doesn’t support .lobster files by path yet.
CAn you give me a multistep file
Yep — here’s a simple multi-step .lobster workflow file that does:
- classify a lead with
llm-task - draft an outreach message using the classification
- require approval before continuing
- print the approved draft
Save this on the gateway machine as:
/home/admin/examples/multistep-lead-workflow.lobster
File contents:
name: multistep-lead-workflow
steps:
- id: classify_lead
command: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"integer","minimum":1,"maximum":5},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
- id: draft_outreach
command: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Using the lead classification, draft a short friendly outreach message. Return JSON only with subject and body.","thinking":"low","input":{"classification":$classify_lead.json},"schema":{"type":"object","properties":{"subject":{"type":"string"},"body":{"type":"string"}},"required":["subject","body"],"additionalProperties":false}}'
- id: approve_draft
command: approve --preview-from-stdin --limit 5 --prompt 'Approve this outreach draft?'
stdin: $draft_outreach.json
approval: required
- id: final_output
command: exec --stdin json --shell 'cat'
stdin: $draft_outreach.json
condition: $approve_draft.approved
Then from Telegram, send:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/home/admin/examples/multistep-lead-workflow.lobster",
"timeoutMs": 60000,
"maxStdoutBytes": 512000
}
If this fails, tell me the exact lobster tool error. Do not try to work around it with shell or the standalone Lobster CLI.
If the $classify_lead.json interpolation fails in your plugin build, tell me the exact error — that’ll mean this Lobster version wants step outputs passed differently, and I’ll rewrite it in the compatible shape.
I get this error
The lobster tool returned this exact error:
workflow command failed (127): /usr/local/bin/openclaw.invoke: 1: 404:: not found
The pipeline path /home/admin/.openclaw/workspace-dba-scout/t.lobster resolved to something that invoked openclaw.invoke, which returned a 404. This suggests the file either doesn't exist at that path or isn't a valid Lobster pipeline definition.
Yep — that error means the file did load, but the workflow step tried to execute openclaw.invoke as a command and hit a broken/missing invoke shim:
/usr/local/bin/openclaw.invoke: 1: 404:: not found
So don’t debug the path yet — the path is being found. The failing bit is openclaw.invoke inside the workflow file.
Here’s a multi-step Lobster file that avoids openclaw.invoke entirely, so it should test file workflows cleanly.
Save as:
/home/admin/.openclaw/workspace-dba-scout/multistep-test.lobster
File contents:
name: multistep-test
steps:
- id: lead
command: >-
node -e 'console.log(JSON.stringify({company:"Acme Dental", industry:"Dental", notes:"Multi-location practice wants missed-call followup and appointment reminders."}))'
- id: score
command: >-
node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const lead = JSON.parse(s); const result = { company: lead.company, fit: "high", priority: 5, reason: "Multi-location dental practice with clear followup/reminder pain." }; console.log(JSON.stringify(result)); })'
stdin: $lead.stdout
- id: draft
command: >-
node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const score = JSON.parse(s); const draft = { subject: `Quick idea for ${score.company}`, body: `Hi — noticed ${score.company} may benefit from faster missed-call followup and appointment reminders. Worth a quick chat?`, score }; console.log(JSON.stringify(draft)); })'
stdin: $score.stdout
- id: review
command: cat
stdin: $draft.stdout
approval: required
- id: final
command: cat
stdin: $draft.stdout
condition: $review.approved
Then send this from Telegram:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Do not run `lobster run`.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/home/admin/.openclaw/workspace-dba-scout/multistep-test.lobster",
"timeoutMs": 60000,
"maxStdoutBytes": 512000
}
If this fails, tell me the exact lobster tool error. Do not try to work around it with shell or the standalone Lobster CLI.
If this works, your .lobster file execution is fine and the remaining issue is specifically openclaw.invoke in workflow-file steps. For now, use openclaw.invoke only in inline Lobster pipelines, or update/report the plugin issue so the workflow-file invoke shim works correctly.
actually /usr/local/bin/openclaw.invoke appears to be corrupt, how do I fix that?
Yep — if /usr/local/bin/openclaw.invoke literally contains 404: then it was probably created from a failed download/install, not a valid executable.
First confirm:
command -v openclaw.invoke
file /usr/local/bin/openclaw.invoke
head -5 /usr/local/bin/openclaw.invoke
If the first line shows 404: or HTML, move it aside and reinstall/update Lobster:
sudo mv /usr/local/bin/openclaw.invoke /usr/local/bin/openclaw.invoke.broken
openclaw plugins update lobster
openclaw plugins doctor
openclaw gateway restart
Then check again:
command -v openclaw.invoke
head -5 "$(command -v openclaw.invoke)"
If openclaw plugins update lobster doesn’t recreate it, do a clean plugin reinstall:
openclaw plugins uninstall lobster
openclaw plugins install @openclaw/lobster
openclaw plugins enable lobster
openclaw gateway restart
One extra gotcha: if command -v openclaw.invoke returns multiple paths depending on shell/PATH, make sure the gateway service sees the fixed one. After restart, rerun the workflow and watch logs:
openclaw logs --follow
Don’t curl a replacement manually unless the Lobster docs/plugin explicitly tell you to — that’s how these 404: shim files usually happen. 🦞
I've updated lobster but /usr/local/bin/openclaw.invoke is no longer there
That’s actually expected after moving/removing the corrupt shim: now you need to reinstall the standalone Lobster CLI/shims, not just the OpenClaw plugin.
The OpenClaw lobster plugin makes the lobster tool available to agents. But when a .lobster workflow file has a step like:
command: openclaw.invoke --tool llm-task ...
that step runs through the system shell, so openclaw.invoke must exist as a real executable in the gateway machine’s PATH.
Try this on the gateway box:
pnpm add -g @openclaw/lobster
command -v lobster
command -v openclaw.invoke
command -v clawd.invoke
If openclaw.invoke now appears somewhere like a pnpm global bin dir, test it:
openclaw.invoke --help
Then restart the gateway:
openclaw gateway restart
If command -v openclaw.invoke works in your shell, but the workflow still says openclaw.invoke: not found, your gateway service probably doesn’t have the pnpm global bin dir in its PATH. In that case, make a stable symlink:
sudo ln -sf "$(command -v openclaw.invoke)" /usr/local/bin/openclaw.invoke
sudo ln -sf "$(command -v clawd.invoke)" /usr/local/bin/clawd.invoke 2>/dev/null || true
openclaw gateway restart
Then rerun the workflow.
Key distinction:
openclaw plugins install @openclaw/lobster= agent tool pluginpnpm add -g @openclaw/lobster= CLI +openclaw.invokeshim for workflow shell steps
You likely need both for .lobster files that call openclaw.invoke.
i don't have pnpm
No problem — install pnpm first, then install the Lobster CLI/shims.
On the gateway box:
corepack enable
corepack prepare pnpm@latest --activate
pnpm --version
Then:
pnpm add -g @openclaw/lobster
command -v openclaw.invoke
openclaw.invoke --help
openclaw gateway restart
If pnpm add -g complains about no global bin directory, run:
pnpm setup
source ~/.bashrc
pnpm add -g @openclaw/lobster
If corepack isn’t available on your system, paste that error — don’t switch to Bun. We’ll get pnpm installed cleanly for your Node setup.
Can i use npm instead?
Yes — npm is fine here.
On the gateway box:
npm install -g @openclaw/lobster
command -v lobster
command -v openclaw.invoke
openclaw.invoke --help
openclaw gateway restart
If npm install -g fails with permissions, use one of these depending on how Node is installed:
sudo npm install -g @openclaw/lobster
or, if you use nvm, don’t use sudo — switch to your Node version and run:
npm install -g @openclaw/lobster
If install succeeds but openclaw.invoke is still not found by the workflow, check where npm put global binaries:
npm config get prefix
ls "$(npm config get prefix)/bin" | grep invoke
Then either add that bin dir to the gateway service PATH, or make a stable symlink:
sudo ln -sf "$(command -v openclaw.invoke)" /usr/local/bin/openclaw.invoke
openclaw gateway restart
So yes: npm install -g @openclaw/lobster is the npm equivalent.
it says it is here but I can't find openclaw.invoke in /home/admin/.npm-global
Ah, that explains it. The npm package with the CLI shims is currently the legacy-named package:
npm install -g @clawdbot/lobster
That package exposes:
lobster
openclaw.invoke
clawd.invoke
After installing, check:
npm bin -g 2>/dev/null || npm prefix -g
find /home/admin/.npm-global -name 'openclaw.invoke*' -o -name 'lobster*'
command -v openclaw.invoke
openclaw.invoke --help
If openclaw.invoke exists under something like:
/home/admin/.npm-global/bin/openclaw.invoke
but the gateway workflow can’t see it, symlink it into /usr/local/bin:
sudo ln -sf /home/admin/.npm-global/bin/openclaw.invoke /usr/local/bin/openclaw.invoke
sudo ln -sf /home/admin/.npm-global/bin/clawd.invoke /usr/local/bin/clawd.invoke
sudo ln -sf /home/admin/.npm-global/bin/lobster /usr/local/bin/lobster
openclaw gateway restart
Small naming mess: @openclaw/lobster is the plugin package name in newer docs, but the standalone CLI/shim package on npm that has openclaw.invoke is @clawdbot/lobster right now.
That has installed it, i get this message for openclaw.invoke -- help
Error: openclaw.invoke requires --url or OPENCLAW_URL
Great — that means the shim is installed correctly now. It just needs to know which OpenClaw Gateway to call.
Set these env vars for the gateway process/workflow environment:
export OPENCLAW_URL=http://127.0.0.1:18789
# If your gateway requires a token:
export OPENCLAW_TOKEN='YOUR_GATEWAY_TOKEN'
Quick manual test:
OPENCLAW_URL=http://127.0.0.1:18789 openclaw.invoke --help
If auth is enabled:
OPENCLAW_URL=http://127.0.0.1:18789 OPENCLAW_TOKEN='YOUR_GATEWAY_TOKEN' openclaw.invoke --help
For the .lobster file, you can bake those vars into the workflow so shell steps inherit them:
name: openclaw-invoke-test
env:
OPENCLAW_URL: http://127.0.0.1:18789
# Better: don’t hardcode tokens in files if you can avoid it.
# OPENCLAW_TOKEN: your-token-here
steps:
- id: greeting
run: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with greeting=hello","schema":{"type":"object","properties":{"greeting":{"type":"string"}},"required":["greeting"],"additionalProperties":false}}'
If a token is required, best practice is to set OPENCLAW_TOKEN in the service/user environment rather than committing it into the .lobster file.
To find the URL/token source on the machine, these usually help:
openclaw gateway status
openclaw dashboard
openclaw dashboard often prints a URL containing the token; don’t paste that publicly.
Now I get this message
Error: openclaw.invoke requires --tool and --action
That one is actually good news: openclaw.invoke is now running, and it’s past the URL/token problem. It’s just being called without the required args.
openclaw.invoke --help apparently doesn’t behave like a normal help command in this build — it still validates that --tool and --action are present.
Test it with a real call instead:
OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='YOUR_GATEWAY_TOKEN_IF_NEEDED' \
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
And in your .lobster file, make sure the step has both --tool and --action, like this:
name: openclaw-invoke-test
env:
OPENCLAW_URL: http://127.0.0.1:18789
# OPENCLAW_TOKEN: your-token-if-required
steps:
- id: test_llm
run: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
Then trigger it from Telegram/OpenClaw with:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/home/admin/.openclaw/workspace-dba-scout/openclaw-invoke-test.lobster",
"timeoutMs": 60000,
"maxStdoutBytes": 512000
}
If you got that error from the workflow, not from your manual --help test, paste the exact run: line from the .lobster file — it probably lost the --tool / --action flags due to quoting or line wrapping.
I get the message
Error: openclaw.invoke failed (401): {"error":{"message":"Unauthorized","type":"unauthorized"}}
Good, that’s the last missing piece: the shim is reaching the Gateway, but it doesn’t have Gateway auth.
openclaw.invoke calls the Gateway HTTP /tools/invoke endpoint, so it needs the same Gateway token/password auth.
If your gateway uses token auth, set:
export OPENCLAW_URL=http://127.0.0.1:18789
export OPENCLAW_TOKEN='your-gateway-token-here'
If it uses password auth, set:
export OPENCLAW_URL=http://127.0.0.1:18789
export OPENCLAW_TOKEN='your-gateway-password-here'
Yes, the shim expects OPENCLAW_TOKEN even when the Gateway auth mode is password — it sends it as Authorization: Bearer ....
To find what auth mode/value you’re using, run on the gateway box:
openclaw gateway status
openclaw config get gateway.auth.mode
openclaw config get gateway.auth.token
openclaw config get gateway.auth.password
Don’t paste the token/password publicly.
Then test with a real invoke:
OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='your-token-or-password' \
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
For the workflow file, either export those vars in the gateway service environment, or add only the URL to the file and keep the token in the environment:
env:
OPENCLAW_URL: http://127.0.0.1:18789
# Do not hardcode OPENCLAW_TOKEN here unless this file is private and locked down.
If you hardcode the token in the .lobster file, treat that file like a secret.
Where can I find my openclaw token
On the gateway machine, check it locally — don’t paste the value here.
Try:
openclaw config get gateway.auth.mode
openclaw config get gateway.auth.token
openclaw config get gateway.auth.password
If gateway.auth.mode is token, use gateway.auth.token as:
export OPENCLAW_TOKEN='that-token-value'
If auth mode is password, use the password value instead:
export OPENCLAW_TOKEN='that-password-value'
You can also run:
openclaw dashboard
That often prints a local dashboard URL containing the gateway token in the #token=... part. Treat that whole URL as secret.
For your Lobster/openclaw.invoke case, you want:
export OPENCLAW_URL=http://127.0.0.1:18789
export OPENCLAW_TOKEN='your-token-or-password'
Docs: https://docs.openclaw.ai/gateway/tools-invoke-http-api
the token is being redacted
Yep, openclaw config get redacts secrets on purpose. To retrieve it for local use, read the raw config file directly on the gateway box — don’t paste the result here.
Try:
CONFIG="$(openclaw config file)"
echo "$CONFIG"
node -e 'const fs=require("fs"); const p=process.argv[1]; const c=fs.readFileSync(p,"utf8"); const m=c.match(/token\s*[:=]\s*["'"'`]([^"'"'`]+)["'"'`]/); console.log(m ? m[1] : "No plaintext token found in config")' "$CONFIG"
If that prints a token, use it like:
export OPENCLAW_URL=http://127.0.0.1:18789
export OPENCLAW_TOKEN='PASTE_TOKEN_HERE'
If it says no plaintext token found, your token may be coming from an env var / SecretRef. Check these locally:
printenv OPENCLAW_GATEWAY_TOKEN
printenv OPENCLAW_TOKEN
printenv OPENCLAW_GATEWAY_PASSWORD
If OpenClaw runs as a systemd user service, also check the service environment:
systemctl --user show openclaw-gateway --property=Environment
If you still can’t recover it, easiest fix is to rotate/set a new gateway token:
openclaw config set gateway.auth.mode token
openclaw config set gateway.auth.token "$(openssl rand -hex 32)"
openclaw gateway restart
openclaw config get gateway.auth.token
That last command may still redact, so read it from the config file right after setting it, or save it as you set it:
TOKEN="$(openssl rand -hex 32)"
openclaw config set gateway.auth.mode token
openclaw config set gateway.auth.token "$TOKEN"
printf '%s
' "$TOKEN" > ~/.openclaw-gateway-token-for-lobster
chmod 600 ~/.openclaw-gateway-token-for-lobster
openclaw gateway restart
Then for Lobster:
export OPENCLAW_TOKEN="$(cat ~/.openclaw-gateway-token-for-lobster)"
ok i ahve the token and have exported it
Perfect. Now test the shim with a real call:
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
If that works, rerun the .lobster workflow from Telegram with the file-path prompt:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/home/admin/.openclaw/workspace-dba-scout/t.lobster",
"timeoutMs": 60000,
"maxStdoutBytes": 512000
}
If the manual openclaw.invoke test works but the workflow still gets 401, then the Gateway service running the Lobster workflow does not inherit your shell export. In that case add the vars to the workflow file temporarily:
env:
OPENCLAW_URL: http://127.0.0.1:18789
OPENCLAW_TOKEN: your-token-here
Longer-term, put OPENCLAW_TOKEN into the gateway service environment instead of hardcoding it in the workflow file.
I'm trying to copy openclaw.invoke to /usr/local/bin but I get permission denied
That’s normal — /usr/local/bin is root-owned. Use sudo, and prefer a symlink instead of copying so it keeps pointing at the installed shim after updates:
sudo ln -sf "$(command -v openclaw.invoke)" /usr/local/bin/openclaw.invoke
sudo ln -sf "$(command -v clawd.invoke)" /usr/local/bin/clawd.invoke
Then verify:
/usr/local/bin/openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
If you don’t have sudo access, don’t use /usr/local/bin. Instead make sure the directory containing openclaw.invoke is in the Gateway service’s PATH. For example, if it’s in /home/admin/.npm-global/bin, the workflow needs that path available when the gateway runs.
I managed to run the prompt but I got this error
tools: lobster failed stack:
Error: workflow command failed (1): openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"integer","minimum":1,"maximum":5},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
at throwOnErrorEnvelope (/home/admin/.openclaw/npm/node_modules/@openclaw/lobster/dist/index.js:175:9)
at /home/admin/.openclaw/npm/node_modules/@openclaw/lobster/dist/index.js:276:20
Nice — that means the workflow file is running now. This stack is just Lobster saying “the openclaw.invoke subprocess exited 1”; it’s hiding the actual openclaw.invoke error.
Most likely causes now are:
- the workflow process does not inherit
OPENCLAW_URL/OPENCLAW_TOKEN llm-taskis not enabled/allowed over/tools/invoke- the
llm-taskcall itself is failing model/auth
First, run the exact command manually on the gateway box, with env inline:
OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='YOUR_TOKEN' \
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"integer","minimum":1,"maximum":5},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
If that works manually, add the env vars to the workflow file for testing:
name: multistep-lead-workflow
env:
OPENCLAW_URL: http://127.0.0.1:18789
OPENCLAW_TOKEN: YOUR_TOKEN
steps:
- id: classify_lead
run: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"integer","minimum":1,"maximum":5},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
Treat that file as secret if it contains the token. Longer-term, put OPENCLAW_TOKEN into the gateway service environment instead.
If the manual command fails too, paste only the non-secret error text. If it says 404, llm-task isn’t exposed/allowed. If it says 401, token/env is wrong. If it says model/auth, then the llm-task plugin can be reached but its model provider config is failing.
I get the message
Error: openclaw.invoke failed (500): {"ok":false,"error":{"type":"tool_error","message":"tool execution failed"}}
That 500 means the bridge/auth is working now, but the llm-task tool itself is failing. The Gateway is sanitizing the error, so the useful detail will be in the logs.
Run this in one terminal:
openclaw logs --follow
Then in another terminal rerun the exact openclaw.invoke ... command. Look for the real llm-task error right after it runs.
Most common cause here: llm-task does not automatically inherit your lead-scout agent model. Configure it explicitly, or pass provider/model in the call.
Try this direct test, adjusting provider/model to your working LM Studio config:
OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='YOUR_TOKEN' \
openclaw.invoke --tool llm-task --action json --args-json '{"provider":"lmstudio","model":"qwen/qwen3.6-35b-a3b","prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
Or set it in config:
{
plugins: {
entries: {
"llm-task": {
enabled: true,
config: {
defaultProvider: "lmstudio",
defaultModel: "qwen/qwen3.6-35b-a3b",
timeoutMs: 30000
}
}
}
}
}
Then restart:
openclaw gateway restart
If the log says tool not found / 404, llm-task still isn’t allowed. If it says model/auth/provider error, paste that sanitized log line and we can fix the provider config next.
I see this is the the logs
tool execution failed: Error: LLM JSON did not match schema: /priority must be integer
Great, that’s a real error now — the whole Lobster/OpenClaw bridge is working. The model returned priority as something like "5" instead of integer 5, and llm-task rejected it because schema validation is strict.
Easiest fix: make priority a string enum instead of an integer. Local models are often sloppy with JSON number types.
Change this part:
"priority":{"type":"integer","minimum":1,"maximum":5}
to:
"priority":{"type":"string","enum":["1","2","3","4","5"]}
Or keep integer but make the prompt stricter:
priority must be a JSON integer number from 1 to 5, not a string. Example: "priority": 5
I’d use the string enum for reliability. Here’s the safer run: line:
run: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
If you really need it as an integer later, convert it in the next deterministic step with Node/jq instead of trusting the model to get the type right.
so can you give me the full command to run again
Yep — run this on the gateway box. Replace YOUR_TOKEN if you haven’t already exported it.
If you already exported OPENCLAW_URL and OPENCLAW_TOKEN:
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
Or with env inline:
OPENCLAW_URL=http://127.0.0.1:18789 \
OPENCLAW_TOKEN='YOUR_TOKEN' \
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
If this works, paste that same --args-json change into your .lobster file’s run: line.
I get this as a response
[
{
"content": [
{
"type": "text",
"text": "{\n "company": "Acme Dental",\n "fit": "high",\n "priority": "4",\n "reason": "Multi-location practice indicates established revenue and clear need for automation (missed-call followup, appointment reminders). Vertical-specific pain points with measurable ROI potential."\n}"
}
],
"details": {
"json": {
"company": "Acme Dental",
"fit": "high",
"priority": "4",
"reason": "Multi-location practice indicates established revenue and clear need for automation (missed-call followup, appointment reminders). Vertical-specific pain points with measurable ROI potential."
},
"provider": "lmstudio",
"model": "qwen/qwen3.6-35b-a3b"
}
}
]
Perfect — that means openclaw.invoke → llm-task → LM Studio is working now ✅
Now update your .lobster file to use the same working schema (priority as a string), then run the file again from Telegram/OpenClaw.
Use this run: line in the workflow:
run: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
Then trigger the file:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/home/admin/.openclaw/workspace-dba-scout/t.lobster",
"timeoutMs": 60000,
"maxStdoutBytes": 512000
}
If that works, you’re fully through the setup gauntlet: plugin installed, invoke shim installed, auth configured, and schema fixed. 🦞
can you give me the full contents of t.lobster
Yep — replace /home/admin/.openclaw/workspace-dba-scout/t.lobster with this full file:
name: t
env:
OPENCLAW_URL: http://127.0.0.1:18789
# Keep OPENCLAW_TOKEN exported in the gateway/service environment.
# Avoid hardcoding it here unless this file is private and locked down.
steps:
- id: classify_lead
run: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
- id: normalize_result
run: >-
node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const raw = JSON.parse(s); const json = Array.isArray(raw) ? raw[0].details.json : raw.details.json; console.log(JSON.stringify({ company: json.company, fit: json.fit, priority: Number(json.priority), reason: json.reason }, null, 2)); })'
stdin: $classify_lead.stdout
- id: draft_outreach
run: >-
node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const lead = JSON.parse(s); const draft = { subject: `Quick idea for ${lead.company}`, body: `Hi — noticed ${lead.company} may benefit from faster missed-call followup and appointment reminders. Based on the lead notes, this looks like a ${lead.fit}-fit opportunity with priority ${lead.priority}. Worth a quick chat?`, lead }; console.log(JSON.stringify(draft, null, 2)); })'
stdin: $normalize_result.stdout
- id: review_draft
run: cat
stdin: $draft_outreach.stdout
approval: required
- id: final_output
run: cat
stdin: $draft_outreach.stdout
condition: $review_draft.approved
Then trigger it again with:
Call the OpenClaw tool named `lobster` directly.
Do not use shell, exec, terminal, node, or the standalone lobster CLI.
Use this exact tool payload:
{
"action": "run",
"pipeline": "/home/admin/.openclaw/workspace-dba-scout/t.lobster",
"timeoutMs": 60000,
"maxStdoutBytes": 512000
}
If you get 401, the workflow still isn’t inheriting OPENCLAW_TOKEN; temporarily add it under env: to confirm, then move it into the service env properly.
which env file should I put these in?
Put it in the gateway’s global env file:
nano ~/.openclaw/.env
Add:
OPENCLAW_URL=http://127.0.0.1:18789
OPENCLAW_TOKEN=your-token-here
Then restart the gateway:
openclaw gateway restart
That’s the right place for a long-running gateway/service. OpenClaw reads ~/.openclaw/.env as the global fallback env file, and workflow shell steps should then inherit it.
Two notes:
- Don’t put this in the workspace
.env(~/.openclaw/workspace-dba-scout/.env). OpenClaw blocksOPENCLAW_*vars from untrusted workspace.envfiles for safety. - Lock it down:
chmod 600 ~/.openclaw/.env
Then rerun the workflow.
I ran the workflow but got this error
The lobster tool failed with this exact error:
Workflow step normalize_result requires run, command, pipeline, approval, or input
This suggests the pipeline file at /home/admin/.openclaw/workspace-dba-scout/t.lobster has a step named normalize_result that's missing a required action field. The pipeline itself may be malformed or incomplete. Want me to take a look at the file to diagnose further?
Yep — that usually means YAML indentation/paste got mangled around normalize_result, or this Lobster build is happier with command: than run:.
Replace the whole file with this version using command: everywhere:
name: t
env:
OPENCLAW_URL: http://127.0.0.1:18789
steps:
- id: classify_lead
command: >-
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
- id: normalize_result
command: >-
node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const raw = JSON.parse(s); const json = Array.isArray(raw) ? raw[0].details.json : raw.details.json; console.log(JSON.stringify({ company: json.company, fit: json.fit, priority: Number(json.priority), reason: json.reason }, null, 2)); })'
stdin: $classify_lead.stdout
- id: draft_outreach
command: >-
node -e 'let s=""; process.stdin.on("data", c => s += c); process.stdin.on("end", () => { const lead = JSON.parse(s); const draft = { subject: "Quick idea for " + lead.company, body: "Hi — noticed " + lead.company + " may benefit from faster missed-call followup and appointment reminders. Based on the lead notes, this looks like a " + lead.fit + "-fit opportunity with priority " + lead.priority + ". Worth a quick chat?", lead }; console.log(JSON.stringify(draft, null, 2)); })'
stdin: $normalize_result.stdout
- id: review_draft
command: cat
stdin: $draft_outreach.stdout
approval: required
- id: final_output
command: cat
stdin: $draft_outreach.stdout
condition: $review_draft.approved
Two things to check carefully:
command:must be indented exactly under- id: normalize_resultstdin:must line up withcommand:, not be nested under it
Then rerun the same Telegram prompt. If it still fails, paste just the normalize_result block from your actual file.
I get this error
Here's the exact error from the lobster tool:
workflow command failed (1): openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
The pipeline at /home/admin/.openclaw/workspace-dba-scout/t.lobster exited with status code 1. It's trying to invoke an llm-task to classify a sales lead ("Acme Dental") but the underlying openclaw.invoke call is failing — likely the llm-task tool call itself errored out (possibly a model/auth issue or the task timed out). Want me to look at the pipeline file to debug further?
That error is still Lobster hiding the real openclaw.invoke stderr. Since the exact same invoke worked manually, the most likely issue is: the workflow process still doesn’t have OPENCLAW_TOKEN.
Two fixes/checks:
- In
~/.openclaw/.env, set both names:
OPENCLAW_URL=http://127.0.0.1:18789
OPENCLAW_TOKEN=your-token-here
OPENCLAW_GATEWAY_TOKEN=your-token-here
Then:
chmod 600 ~/.openclaw/.env
openclaw gateway restart
- Temporarily replace the first step with this debug wrapper so we can see the actual error without leaking the token:
- id: classify_lead
command: >-
sh -lc 'echo "OPENCLAW_URL=${OPENCLAW_URL:-missing}" >&2; if [ -z "$OPENCLAW_TOKEN" ]; then echo "OPENCLAW_TOKEN=missing" >&2; else echo "OPENCLAW_TOKEN=set" >&2; fi; openclaw.invoke --tool llm-task --action json --args-json '\''{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'\'''
Then run the workflow while tailing logs:
openclaw logs --follow
If logs show OPENCLAW_TOKEN=missing, the gateway didn’t load the env file. If it shows OPENCLAW_TOKEN=set but still fails, the next log line should show the real openclaw.invoke error.
This is the error from openclaw logs
09:47:59
debug
tools: lobster failed stack:
Error: workflow command failed (1): openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'
at throwOnErrorEnvelope (/home/admin/.openclaw/npm/node_modules/@openclaw/lobster/dist/index.js:175:9)
at /home/admin/.openclaw/npm/node_modules/@openclaw/lobster/dist/index.js:276:20
09:47:59
error
[tools] lobster failed: workflow command failed (1): openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}' raw_params={"action":"run","pipeline":"/home/admin/.openclaw/workspace-dba-scout/t.lobster","timeoutMs":60000,"maxStdoutBytes":512000}
That log is still only Lobster’s wrapper error — it isn’t showing the actual openclaw.invoke stderr. Let’s make the workflow print the inner error directly.
Temporarily replace t.lobster with this debug-only version:
name: t-debug
env:
OPENCLAW_URL: http://127.0.0.1:18789
steps:
- id: debug_invoke
command: >-
sh -lc 'echo "OPENCLAW_URL=${OPENCLAW_URL:-missing}"; if [ -z "$OPENCLAW_TOKEN" ]; then echo "OPENCLAW_TOKEN=missing"; else echo "OPENCLAW_TOKEN=set"; fi; openclaw.invoke --tool llm-task --action json --args-json '\''{"prompt":"Classify this sales lead. Return JSON only with company, fit, priority, and reason. priority must be a string from 1 to 5.","thinking":"low","input":{"company":"Acme Dental","notes":"Multi-location dental practice looking for help with missed-call followup and appointment reminders."},"schema":{"type":"object","properties":{"company":{"type":"string"},"fit":{"type":"string","enum":["high","medium","low"]},"priority":{"type":"string","enum":["1","2","3","4","5"]},"reason":{"type":"string"}},"required":["company","fit","priority","reason"],"additionalProperties":false}}'\'' 2>&1; echo "exit_code=$?"'
Important: this intentionally does not fail the workflow; it prints the real inner error/result instead.
Run the same Telegram prompt again. The output should say one of:
OPENCLAW_TOKEN=missing→ gateway service isn’t inheriting your token env401 Unauthorized→ token value isn’t reaching/valid500 tool execution failed→ then check logs for the llm-task schema/model error- JSON result → invoke is working inside Lobster, and we can restore the normal multi-step file
If it says token missing, easiest confirmation is to add this under env: temporarily:
OPENCLAW_TOKEN: your-token-here
Treat that file as secret if you do that.
I ran it and got this
Same result as before:
• Lobster tool: ok: true, status: ok (the runtime itself succeeded)
• Pipeline exit code: 1 (the command inside failed)
• Output: OPENCLAW_URL=http://127.0.0.1:18789, OPENCLAW_TOKEN=***, exit_code=1
The openclaw.invoke command inside the pipeline is failing with exit code 1. The token is set (masked in output), so it's not a missing-token issue. The failure is likely from the llm-task tool call itself — possibly the model isn't available, auth is wrong, or the tool invocation is failing for another reason.
Good debug result: token is present, but we still don’t have the actual openclaw.invoke stderr. Let’s force it into files and print it back.
Replace t.lobster temporarily with this:
name: t-debug
env:
OPENCLAW_URL: http://127.0.0.1:18789
steps:
- id: debug_invoke
command: >-
sh -lc 'rm -f /tmp/oc-invoke.out /tmp/oc-invoke.err; echo "OPENCLAW_URL=${OPENCLAW_URL:-missing}"; if [ -z "$OPENCLAW_TOKEN" ]; then echo "OPENCLAW_TOKEN=missing"; else echo "OPENCLAW_TOKEN=set length=${#OPENCLAW_TOKEN}"; fi; command -v openclaw.invoke; openclaw.invoke --tool llm-task --action json --args-json '\''{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'\'' >/tmp/oc-invoke.out 2>/tmp/oc-invoke.err; code=$?; echo "exit_code=$code"; echo "--- stdout ---"; cat /tmp/oc-invoke.out 2>/dev/null || true; echo "--- stderr ---"; cat /tmp/oc-invoke.err 2>/dev/null || true; exit 0'
Run the same Telegram prompt again. This should show the real error under --- stderr ---.
Two likely outcomes:
401 Unauthorizedeven though token is set → the token in the workflow env is not the same token your gateway expects. Re-copy it into~/.openclaw/.env, restart gateway, retry.500 tool execution failed→openclaw.invokeis reaching the gateway and auth is fine; then tail logs immediately after this run for the actualllm-taskerror.
Also: since the same openclaw.invoke worked manually, compare the token length from this workflow output with your shell:
echo ${#OPENCLAW_TOKEN}
If the lengths differ, the gateway workflow is using an older/different token from ~/.openclaw/.env.
ame result:
• Lobster tool: ok: true, status: ok
• Pipeline exit code: 1
• Output: OPENCLAW_URL=http://127.0.0.1:18789, OPENCLAW_TOKEN=set length=48, /usr/local/bin/openclaw.invoke, exit_code=1
• Stdout/stderr: empty
The openclaw.invoke command is failing silently — no error output at all. The token is set (48 chars) and the URL is correct, but the command produces no output and exits with code 1.
Aha — silent exit code 1 with empty stdout/stderr points to the openclaw.invoke shim itself failing before it can print anything.
The shim is not the real invoker; it internally runs the lobster binary. So inside the workflow environment, /usr/local/bin/openclaw.invoke is found, but lobster probably is not in PATH.
Fix by symlinking lobster too:
command -v lobster
ls -l /usr/local/bin/openclaw.invoke
sudo ln -sf "$(command -v lobster)" /usr/local/bin/lobster
sudo ln -sf "$(command -v openclaw.invoke)" /usr/local/bin/openclaw.invoke
sudo ln -sf "$(command -v clawd.invoke)" /usr/local/bin/clawd.invoke
/usr/local/bin/lobster --help | head
/usr/local/bin/openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'
openclaw gateway restart
Then run the workflow again.
If you want to confirm before changing anything, make the debug workflow run this:
command: >-
sh -lc 'echo PATH=$PATH; command -v openclaw.invoke || true; command -v lobster || true; /usr/local/bin/openclaw.invoke --tool llm-task --action json --args-json '\''{"prompt":"Return JSON with ok=true","schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}'\'' 2>&1; echo exit_code=$?'
If command -v lobster is blank, that’s the bug.
ok, finally everything is working as expected
Yesss, excellent — that was a proper gauntlet. 🦞
Final working checklist for future readers:
- install/enable the OpenClaw
lobsterplugin - install the standalone Lobster CLI/shims (
@clawdbot/lobstercurrently providesopenclaw.invoke) - ensure
openclaw.invoke,clawd.invoke, andlobsterare all on the Gateway service PATH, or symlink them into/usr/local/bin - set
OPENCLAW_URL+OPENCLAW_TOKENin~/.openclaw/.env - use a schema the model reliably satisfies
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow indexes the solution for the next person.