#Webhook issues after updating openclaw

1 messages ¡ Page 1 of 1 (latest)

torpid temple
#

Context: Debugging webhook server → ngrok → Trello routing for Idea Pipeline.

What's working:

• Webhook server running on 127.0.0.1:3003 (verified: ss + curl /health)
• Webhook server responds correctly to POST requests locally
• Trello webhook registered and active

The problem:
Ngrok static URL (https://jacoby-aglimmer-mortally.ngrok-free.dev (https://jacoby-aglimmer-mortally.ngrok-free.dev/)) is forwarding to port 4040 instead of port 3003:

Forwarding: https://jacoby-aglimmer-mortally.ngrok-free.dev -> http://127.0.0.1:4040
Expected: https://jacoby-aglimmer-mortally.ngrok-free.dev -> http://127.0.0.1:3003

Port 4040 is ngrok's inspector UI, not our webhook server.

What we've tried:

  1. Kill all ngrok processes: killall -9 ngrok
  2. Start ngrok with explicit address: /snap/bin/ngrok http 127.0.0.1:3003
  3. Checked for config files: ~/.config/ngrok/ngrok.yml, ~/.ngrok2/ngrok.yml (none exist)
  4. Checked systemd: systemctl status ngrok (not found)
  5. Verified webhook server is listening on 3003: ss -tlnp | grep :3003 ✅
  6. Tested webhook server directly: curl http://127.0.0.1:3003/health ✅

The question:
Why is ngrok ignoring the http 127.0.0.1:3003 argument and forwarding to port 4040 instead? Is there account-level static URL configuration that overrides command-line arguments?

Environment:

• OS: Linux 5.15.0-170-generic (Kamatera VPS)
• Ngrok: /snap/bin/ngrok (version 3.36.1)
• Static URL: jacoby-aglimmer-mortally.ngrok-free.dev (free plan)

Need help getting ngrok to forward to the correct port!

real beaconBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

fathom haloBOT
#

ngrok will only forward to 127.0.0.1:4040 if something told it to tunnel to 4040 (that’s the local ngrok inspector UI). There isn’t an “account-level override” that silently rewrites the upstream port for a plain ngrok http … run — so this is almost always (a) you’re not actually running the process you think you are, or (b) there’s a config/service somewhere (snap…) starting a tunnel to 4040.

Here’s the fastest way to pinpoint it:

1) Confirm you don’t have a snap-managed ngrok daemon auto-starting

Snap packages can run as services and respawn after killall.

snap services | grep -i ngrok || true
pgrep -a ngrok

If you see a service, stop/disable it, then retry:

sudo snap stop --disable ngrok
#
# (or: sudo snap stop ngrok)

2) Find the actual config file ngrok is using (v3)

ngrok v3 can tell you exactly where it’s reading config from:

ngrok config check
ngrok config show

On snap installs, the config is often not in ~/.config/ngrok/… — it can live under snap’s dirs (commonly things like ~/snap/ngrok/common/… or /var/snap/ngrok/common/…). Look in that config for anything tunneling addr: 4040.

Also check you’re not overriding via env var:

#
env | grep -i NGROK

3) Start the tunnel with an explicit domain + port

If you’re trying to use your reserved dev domain, be explicit:

/snap/bin/ngrok http --domain=jacoby-aglimmer-mortally.ngrok-free.dev 3003

If it’s still forwarding to 4040…

Paste the output of:

  • ngrok config check
  • ngrok config show (redact tokens)
  • pgrep -a ngrok
#

That’ll make the culprit obvious (usually a snap service or a tunnel definition pointing at 4040).

torpid temple
#

✅ Webhook Server: Running solidly on port 3003

• Health check passes: {"status":"ok"}
• Middleware fixed (raw body capture before bodyParser)
• Can handle POST requests locally

⚠️ Ngrok: Tunnel is starting but not fully connecting

• Running with: /snap/bin/ngrok http jacoby-aglimmer-mortally.ngrok-free.dev:3003
• Logs show: "started tunnel" but tunnel API reports local_address: null
• Static domain config only has authtoken (no tunnel definitions)
• Public URL requests hang (stuck in TLS handshake)

What we found:

• Ngrok config at /home/yucky/snap/ngrok/350/.config/ngrok/ngrok.yml
• When started with explicit domain:port, it creates tunnel correctly
• BUT tunnel-to-backend connection isn't stabilizing

Suggestion from Krill:
The static domain might have an Agent Endpoint configuration in ngrok dashboard that's interfering.

fathom haloBOT
#

That ngrok invocation is almost certainly the root of the weirdness:

1) Your command syntax is wrong for “static dev domain”

You’re running:

/snap/bin/ngrok http jacoby-aglimmer-mortally.ngrok-free.dev:3003

In ngrok v3, the public URL is set via --url (per ngrok docs), and the positional argument is the local upstream (port/url).

Use:

/snap/bin/ngrok http 3003 --url=https://jacoby-aglimmer-mortally.ngrok-free.dev
# (or add 127.0.0.1:3003 explicitly if you prefer)
#

When you pass jacoby-...:3003 without --url, ngrok can treat that as the upstream address, which can lead to “tunnel started” but no stable upstream / odd local_address reporting.

2) Verify locally that ngrok now sees the upstream

After starting with --url, check:

curl -s http://127.0.0.1:4040/api/tunnels

You want to see local_address like http://localhost:3003 (or similar). If it’s still null, run with debug logs:

/snap/bin/ngrok http 3003 --url=https://jacoby-aglimmer-mortally.ngrok-free.dev --log=stdout --log-level=debug

and paste the first error that mentions upstream / dial / connect.

#

3) TLS handshake hanging: quick IPv4/IPv6 sanity check

From any machine:

curl -4vk https://jacoby-aglimmer-mortally.ngrok-free.dev/
curl -6vk https://jacoby-aglimmer-mortally.ngrok-free.dev/

If -4 works but -6 hangs, it’s an IPv6 reachability issue on the client side (surprisingly common with VPS/providers).

4) The dashboard “endpoint” idea (only if still broken)

ngrok has a separate concept of Cloud Edge Endpoints in the dashboard. If you created an endpoint there with the same URL, it can conflict with what the agent is trying to claim.

So if the above still doesn’t fix it, check the ngrok dashboard for an Endpoint using https://jacoby-aglimmer-mortally.ngrok-free.dev and remove/disable it.

If you paste:

  • the output of curl -s http://127.0.0.1:4040/api/tunnels
#
  • and the first ~30 lines of the --log-level=debug run
    …I can tell you exactly which failure mode you’re in.
torpid temple
#

Update: Ngrok still stuck in TLS handshake

Current state:

• ✅ Webhook server: Running solidly on 127.0.0.1:3003
• ✅ Ngrok: Running with correct syntax: ngrok http 127.0.0.1:3003 --url=https://fake-fake-.fake.ngrok-free.dev
• ✅ Logs show: started tunnel addr=http://127.0.0.1:3003
• ❌ Tunnel API: Still shows local_address: null, state: null
• ❌ Public requests: Stuck in TLS handshake (no response)

The pattern:

• ngrok starts and logs "started tunnel"
• Makes initial tunnel API call (200 OK)
• But never establishes stable connection to backend
• Tunnel API never reports online state

Hypothesis: There's something about the Kamatera VPS / ngrok free static domain combination that's causing instability.

fathom haloBOT
#

If ngrok logs “started tunnel” but the local inspector API still shows local_address: null / state: null, that usually means the agent never actually got an online session to ngrok’s edge (so the public URL will just sit there and clients will hang waiting for a backend that never comes up).

At this point I’d stop focusing on the webhook server (yours is fine) and focus on agent↔ngrok connectivity:

1) Run ngrok’s built-in connectivity test (this is the big one)

ngrok has a diagnose command specifically for “agent can’t connect” cases:

/snap/bin/ngrok diagnose --write-report diagnose.txt

Optional but useful (tests IPv6 + multiple PoPs):

/snap/bin/ngrok diagnose --ipv6 true --region all --write-report diagnose.txt
#

Then paste the summary/errors from diagnose.txt.

2) Verify whether the VPS can maintain the outbound tunnel connection

From the VPS, while ngrok is running:

ss -tnp | grep ngrok || true

You should see established outbound connections (typically to ngrok on 443). If you see none / they flap constantly, it’s egress/firewall/provider filtering.

3) Check if this is actually an IPv6 hang (common “TLS handshake stuck” cause)

From wherever you’re testing the public URL:

curl -4vk https://fake-fake-.fake.ngrok-free.dev/health
#
curl -6vk https://fake-fake-.fake.ngrok-free.dev/health

If -4 works and -6 hangs, it’s an IPv6 reachability issue on the client side (and Trello/other services may behave differently depending on their network).

4) Paste the exact local API output (don’t paraphrase)

This will clarify if there’s actually a tunnel object and it’s just missing fields vs no tunnel at all:

curl -s http://127.0.0.1:4040/api/tunnels

If you share:

  • ngrok diagnose report summary
  • curl http://127.0.0.1:4040/api/tunnels raw output
  • first ~30 lines of --log-level=debug output (if needed)
#

…I can tell whether this is (a) egress blocked from the Kamatera VPS, (b) IPv6 blackhole, (c) URL/domain not being claimed, or (d) something snap-specific.

torpid temple
#

Quick Question for Krill - Safe openclaw.json Edit

We found the issue: hooks.mappings expects "planning-agent" but agents.list has "planning-agent" (with "i").

We need to fix openclaw.json but want to do it safely to avoid:

• Crashing openclaw
• Scrambling agents or telegram channels

Question: What's the proper way to update ~/.openclaw/openclaw.json? Is there a config command or should we read → edit → write back?

Context:

• cat ~/.openclaw/openclaw.json | jq shows current structure
• Need to fix agents.list AND hooks.mappings[0].sessionKey (typo)
• Want to preserve all other config intact

What's the safest approach? 🦞

fathom haloBOT
#

Safest way is don’t hand-edit the file — use the built-in CLI so you only touch the exact keys and keep everything else intact.

0) Make sure you’re editing the same config the Gateway service is using

Run:

openclaw gateway status

Check it shows:

  • Config (service): ~/.openclaw/openclaw.json (or whatever path you expect)

If it’s a different path/profile, fix that first (otherwise you’ll edit the wrong file and nothing changes).

1) Backup the config (one-liner)

#
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak.$(date +%F-%H%M%S)

2) Inspect the current values via CLI (avoid jq if it’s JSON5)

openclaw config get hooks.mappings[0].sessionKey
openclaw config get agents.list
openclaw agents list # shows the canonical agent ids

3) Fix only the typo(s) with targeted config set

For the hook mapping string, this is typically enough:

openclaw config set hooks.mappings[0].sessionKey planning-agent
#

If you truly also need to fix an entry inside agents.list, edit the specific index (don’t rewrite the whole array):

openclaw config set 'agents.list[0]' planning-agent
# (use whatever index is wrong)

4) Verify + reload

openclaw config get hooks.mappings[0].sessionKey
openclaw status

Config reload is hot by default (hybrid), but if things still look stale after the change, do:

#
openclaw gateway restart

If you paste the outputs of openclaw config get agents.list and the exact hooks.mappings[0] object (redact tokens), I can tell you the minimal single change you need (often it’s just the sessionKey typo).

torpid temple
#

Krill: Here's the minimal fix 🦞

Current openclaw.json:

{
"agents": {
"defaults": {...},
"list": [
{"id": "planning-agent", "workspace": "..."}, ← CORRECT
{"id": "planning-agent", "workspace": "..."}, ← TYPO (should be "planniing-agent")
...
]
},
"hooks": {
"mappings": [
{
"match": {"path": "trello", "source": "trello❌xxxxxxxxxxxxxxxxxxxxideas"},
"sessionKey": "hook:trello:{{cardId}}}", ← TYPO (typo, no "i")
...
}
]
}
}

Minimal change needed:

Just fix the typo in hooks.mappings[0].sessionKey:

"sessionKey": "hook:trello:{{cardId}}}", ← Change to "i"

OR via jq filter:

cat ~/.openclaw/openclaw.json | jq '.hooks.mappings[0].sessionKey = "hook:trello:{{cardId}}i}}"'

This should resolve the ID mismatch so Gateway can spawn "planniing-agent" when cards move to "ideas".

Does this look right? 🦞

fathom haloBOT
#

Not quite — that proposed sessionKey change (“add an i”) doesn’t line up with what sessionKey is for, and it also looks like it would break your template.

A few key points:

1) hooks.mappings[*].sessionKey is a session identifier, not an agent id

Changing:

  • "hook:trello:{{cardId}}}" → "hook:trello:{{cardId}}i}}"

would (a) create a different session key, and (b) likely make the template invalid. It won’t magically make OpenClaw pick a different agent unless your Trello hook code is (weirdly) parsing agent ids out of sessionKey.

Also: {{cardId}}} having three closing braces strongly suggests the typo is actually just an extra }. If you’re using moustache-style templates, the “minimal fix” is more likely:

  • "hook:trello:{{cardId}}}" → "hook:trello:{{cardId}}"

2) You do have a real config problem: duplicate agent ids

This is the part that can definitely cause “can’t spawn the agent / routing mismatch” behavior:

#
{"id": "planning-agent", ...},
{"id": "planning-agent", ...}, // should be planniing-agent (or whatever you intended)

Agent id should be unique. If you intended a second agent, fix that second .id (and then fix any references to it elsewhere).

3) Safest way to apply the minimal change(s): openclaw config set

Don’t use jq here (your config is JSON5, and cat file | jq ... doesn’t write back anyway).

Do:

  1. Backup:
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak.$(date +%F-%H%M%S)
#
  1. Fix only the exact field:
  • Fix the extra brace (if that’s the typo):
openclaw config set 'hooks.mappings[0].sessionKey' 'hook:trello:{{cardId}}'
  • Fix the duplicated agent id (example index 1):
openclaw config set 'agents.list[1].id' 'planniing-agent'
  1. Verify:
openclaw config get hooks.mappings[0].sessionKey
openclaw config get 'agents.list[1].id'
#
openclaw agents list

If you paste the full hooks.mappings[0] object (redact the source token), I can tell you which field actually names the agent (often it’s agentId / toAgent / similar) so you don’t end up “fixing” sessionKey when the real mismatch is somewhere else.

torpid temple
#

Current hooks.mappings:

{
"match": {
"path": "trello",
"source": "trello:69954999b08427642697df39:review"
},
"action": "agent",
"sessionKey": "hook:trello:{{cardId}}",
"messageTemplate": "REVIEW TASK: {{cardName}}..."
}
Missing: No "agent": "review-agent" field!

What's supposed to be there:

{
"match": {...},
"action": "agent",
"agent": "review-agent", ← MISSING!
"sessionKey": "...",
"messageTemplate": "..."
}
This means:

The webhook dispatches to Gateway
Gateway sees "action": "agent" but doesn't know WHICH agent
Gateway probably defaults to main or fails to spawn the correct agent
Planning agent got lucky somehow (maybe because it was first or there's fallback logic)
Review agent never spawned because Gateway doesn't know to use "review-agent"

📋 Question for Krill:

Subject: hooks.mappings missing agent field - agents not spawning correctly

Context:
Working on Idea Pipeline with Gateway hooks routing. When cards move to Trello lists, webhooks dispatch to Gateway but agents aren't spawning correctly.

Issue:
The hooks.mappings in ~/.openclaw/openclaw.json have "action": "agent" but no "agent" field specifying which agent ID to use.

Current mapping (review stage):

{
"match": {
"path": "trello",
"source": "trello:69954999b08427642697df39:review"
},
"action": "agent",
"sessionKey": "hook:trello:{{cardId}}",
"messageTemplate": "REVIEW TASK: {{cardName}}\n\nFollow shared workflow contract + your AGENTS.md pipeline rules."
}
Missing field:
"agent": "review-agent" ← Should specify which agent to spawn

Question:
How should hooks.mappings specify which agent to spawn? Is there an agent field? If so, can you help me update the mappings to include:

"agent": "planning-agent" for ideas stage
"agent": "review-agent" for review stage
"agent": "coding-agent" for plans stage
"agent": "delivery-agent" for delivered stage
Config location: ~/.openclaw/openclaw.json
Board ID: 69954999b08427642697df39 (Idea Pipeline board)

fathom haloBOT
#

Yep — for action: "agent" the field you’re missing is agentId (not agent). That’s why it’s defaulting/falling back.

Docs reference (shows agentId inside hooks.mappings): https://docs.openclaw.ai/automation/webhook

What your mapping should look like

{
match: { path: "trello", source: "trello:6995...:review" },
action: "agent",
agentId: "review-agent",
sessionKey: "hook:trello:{{cardId}}",
messageTemplate: "REVIEW TASK: {{cardName}}..."
}

Safest way to apply it (no manual editing)

  1. Backup:
#
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak.$(date +%F-%H%M%S)
  1. Set the missing field on the correct mapping index (example: index 0):
openclaw config set 'hooks.mappings[0].agentId' review-agent
  1. Important: make sure your allowlist permits explicit agent routing
    If hooks.allowedAgentIds is currently ["hooks","main"], your new agentId will be ignored.

To allow just your pipeline agents:

openclaw config set --json hooks.allowedAgentIds '["planning-agent","review-agent","coding-agent","delivery-agent"]'
#

(or omit the allowlist / include "*" if you truly want “any agent allowed”.)

  1. Verify:
openclaw config get 'hooks.mappings[0].agentId'
openclaw config get hooks.allowedAgentIds
openclaw agents list

If you paste your full hooks.mappings array (redact tokens), I can tell you the exact indices to run config set against for ideas/review/plans/delivered.

torpid temple
#

message 1 of 6: Chunk 1 (Context & Summary)

We've been debugging the Idea Pipeline with Gateway hooks routing. Successfully tested:

✅ Planning Agent: Spawns, creates PLAN.md, moves card to Review
✅ Review Agent: Spawns, validates, moves card to Plans
✅ Coding Agent: Spawns, implements, moves card to Delivered
❌ Delivery Agent: DOES NOT SPAWN despite Gateway dispatch returning OK
What We Know:

Webhook Flow (verified via webhook logs):
12:59:56.258Z - Card moved: Plans → Delivered
card.id: 699914cf8734ddcc5139a3f6
source: trello:69954999b08427642697df39:delivered
sessionKey: hook:trello:699914cf8734ddcc5139a3f6
Gateway dispatch: {"ok":true,"runId":"a99cb42f-6268-4553-8c2f-2ef204a37785"}
Gateway Response:
HTTP Status: Unknown (always shows this)
Response body: {"ok":true,"runId":"a99cb42f-6268-4553-8c2f-2ef204a37785"}
runId: Valid UUID, indicates dispatch accepted
Sessions Check:
openclaw sessions list --activeMinutes 60 | grep -i "delivery"
Result: No delivery-agent sessions found
Trello API Check:
Card actions show:

Plans→Delivered move (by coding-agent)
Delivered→Delivered self-move (by coding-agent)
Coding-agent routing comment (✅)
No delivery-agent comments

#

Chunk 2 - Agent Workspace & Mappings

Agent Configuration (verified):
~/.openclaw/openclaw.json → agents.list:
{
"id": "delivery-agent",
"workspace": "/home/yucky/.openclaw/workspace-delivery-agent"
}
hooks.mappings Configuration (verified):
{
"match": {
"path": "trello",
"source": "trello:69954999b08427642697df39:delivered"
},
"action": "agent",
"agentId": "delivery-agent",
"sessionKey": "hook:trello:{{cardId}}",
"messageTemplate": "DELIVERY TASK: {{cardName}}..."
}
Status: All mapping fields look correct. No hooks.allowedAgentIds configured.

Chunk 3 - Gateway Status

Gateway Runtime (verified):
openclaw gateway status
Runtime: running (pid 24425)
Listening: 127.0.0.1:18789
Gateway Logs Check:
openclaw gateway logs | grep -i "delivered"
Result: No delivery-related entries found
Note: Gateway logs show dispatch to webhook (trello endpoint), but no detailed spawn logs visible. This might be expected if spawn happens in another process.

#

Chunk 4 - Delivery Agent AGENTS.md

Trigger Detection:
The delivery-agent AGENTS.md expects to be spawned directly by Gateway hooks, but doesn't have explicit trigger format check like the other agents do.

Dependencies:
Uses /home/yucky/.openclaw/workspace/crm/workflow/delivery-validation.js
Uses /home/yucky/.openclaw/workspace/crm/workflow/trello-client.js
Both files verified to exist
Chunk 5 - Test Evidence

Test Card Location:
Currently in "Delivered" list (expected, since coding-agent moved it there).

Test Artifacts Created:
/home/yucky/.openclaw/workspace-main/phase2-routing-test-cd466059/evidence.json
/home/yucky/.openclaw/workspace-main/phase2-routing-test-cd466059/STATUS.md
What's Missing:
DELIVERY_REPORT.md - Not created in phase2-routing-test folder
Validation comment on Trello card - Not added
Card move to "Done" or "Needs Attention" - Not executed

#

Chunk 6 - Core Issue

The Problem:
Gateway successfully dispatches for "delivered" stage:

Returns {"ok":true,"runId":"a99cb42f-6268-4553-8c2f-2ef204a37785"}
But delivery-agent session is never created
Possible Causes:
Gateway silently fails to spawn - Accepts dispatch but errors out without logging
Delivery-agent crashes immediately - Spawns but exits before doing anything
hooks.allowedAgentIds blocking - Even though it's not configured, might be defaulting to deny unknown agent IDs
Permission issue - Delivery-agent workspace has permission problem
Gateway spawn bug specific to delivery-agent - Other agents work, this one doesn't
Chunk 7 - Questions for Krill

How can we debug Gateway spawn behavior for delivery-agent specifically?
Is there additional logging we can enable to see what Gateway does when it receives a "delivered" dispatch? Can we trace the full spawn request/response cycle?

Should we configure hooks.allowedAgentIds?
Should we add this to explicitly allow delivery-agent (and all pipeline agents) to ensure there's no allowlist blocking?

openclaw config set --json hooks.allowedAgentIds '["planning-agent","review-agent","coding-agent","delivery-agent","main"]'
Is there a Gateway bug where agentId "delivery-agent" fails to spawn?
Are there known issues with specific agent IDs where Gateway might not spawn certain agents even with valid configuration?

How can we get more detailed Gateway logs?
The openclaw gateway logs command doesn't support filters. Is there another way to see detailed spawn logs for delivery-agent dispatch specifically?

Chunk 8 - Request Summary

We need help debugging why Gateway dispatch succeeds for "delivered" stage but delivery-agent never spawns. All other agents work correctly.

Priority: URGENT (12+ hours debugging this pipeline)

Please advise on debugging approach and answer any of the above questions! 🦞

#

Final message: Please help!

fathom haloBOT
#

Those artifacts landing under ~/.openclaw/workspace-main/... are a strong signal that the main/default agent is still the one running (or at least the one creating the test folder) — which fits perfectly with your earlier finding: action: "agent" but no agentId (or agentId not allowed) ⇒ fallback.

A tight checklist to get “Delivered → delivery-agent” actually firing:

1) Confirm the mapping uses agentId (not agent) and that it’s allowed

In OpenClaw webhooks, the field is agentId. Docs: https://docs.openclaw.ai/automation/webhook

For your “delivered” mapping, you want:

{
match: { path: "trello", source: "trello:6995...:delivered" },
action: "agent",
agentId: "delivery-agent",
sessionKey: "hook:trello:{{cardId}}",
messageTemplate: "DELIVERY TASK: {{cardName}} ..."
#

To debug “dispatch accepted (ok:true, runId=…) but delivery-agent never spawns”, treat it like an async job: the HTTP response only means “queued/accepted”, not “agent ran successfully”.

Here’s the fastest way to get a definitive answer.

1) Verify routing is even allowed + agent exists

Agent id in mappings is agentId (not agent). Your delivered mapping should have it.

Run:

openclaw agents list
openclaw config get hooks.allowedAgentIds

Interpretation:

  • If hooks.allowedAgentIds is missing / null → explicit agentId routing is allowed (default is allow-all).
#

If the webhook returns {"ok":true,"runId":"…"} but no delivery-agent session ever appears, the only reliable way forward is to correlate that runId in the gateway file logs and separately prove whether delivery-agent can be spawned at all.

Do these 3 checks in order (fast, high-signal):

A) Prove the gateway can spawn delivery-agent (bypass hooks entirely)

Run:

openclaw agent --agent delivery-agent --message "smoke test: reply OK" --json
  • If this fails → it’s an agent/workspace/config problem (not Trello).
  • If this works → it’s hook mapping / allowlist / match logic.

B) Confirm hooks routing isn’t being silently blocked

Run:

#
}

Then make sure your allowlist isn’t blocking it:

openclaw config get hooks.allowedAgentIds

If it’s currently ["hooks","main"], explicit agent routing will be ignored. Set it to include your pipeline agents:

openclaw config set --json hooks.allowedAgentIds '["planning-agent","review-agent","coding-agent","delivery-agent"]'

…and add the missing field (adjust index as needed):

#
  • If it exists and does not include delivery-agent → the gateway will ignore your agentId (and fall back).

If you want to remove any doubt, explicitly allow your pipeline agents:

openclaw config set --json hooks.allowedAgentIds '["planning-agent","review-agent","coding-agent","delivery-agent","main","hooks"]'

(You can omit main/hooks if you don’t use them; I include them because many setups do.)

2) Smoke-test delivery-agent directly (bypasses webhook mapping entirely)

This answers “can the gateway spawn delivery-agent at all?” in one command:

openclaw agent --agent delivery-agent --message "smoke test: reply with OK" --json
#
openclaw config get hooks.allowedAgentIds
openclaw agents list
  • If hooks.allowedAgentIds exists and doesn’t include delivery-agent, add it (and your other pipeline agents).
  • In mappings the field is agentId (not agent).

C) Trace the exact hook run via runId in file logs

First get the log file path:

openclaw gateway status

It prints File logs: ... (often /tmp/openclaw/openclaw-YYYY-MM-DD.log). Then:

#
openclaw config set 'hooks.mappings[<N>].agentId' delivery-agent

2) Verify the mapping is actually matching the incoming request

Two common “it ran but not the right one” causes:

  • You’re POSTing to the wrong endpoint (your mapping has match.path: "trello" → the URL must be /hooks/trello)
  • match.source doesn’t exactly match the payload you’re sending (case/typo/list name mismatch)

Easiest way to confirm: tail logs while you trigger a single Trello event:

openclaw logs --follow --plain --limit 200

You should see a line that indicates which mapping matched + what action it resolved to. If you don’t, it’s not matching.

#

If this fails, it’s not a Trello/mapping problem — it’s something about that agent/workspace/config.

3) Trace the specific run via logs using the runId

You already have a runId. Use it as your correlation key.

First, find the gateway file log path:

openclaw gateway status

It will show something like: /tmp/openclaw/openclaw-YYYY-MM-DD.log

Then:

#
grep -n "a99cb42f-6268-4553-8c2f-2ef204a37785" /tmp/openclaw/openclaw-*.log | tail -200

That will tell us why it accepted but didn’t run (blocked agentId, unknown agentId fallback, session-store error, workspace error, crash, etc.).

Paste these 4 outputs and I can tell you exactly what’s wrong

  1. openclaw --version
  2. openclaw config get hooks.allowedAgentIds
  3. Result JSON of the smoke test command in (A)
  4. The grep runId snippet in (C)

Once we see the log line around that UUID, this stops being “12-hour mystery” and becomes a single config fix or a known-version bug/workaround.

#

3) If delivery-agent is running, the output may be in the delivery agent workspace, not workspace-main

If the hook is routed correctly, the run happens in the resolved agent’s workspace. So check:

openclaw agents list

and look at the delivery-agent workspace path. Your DELIVERY_REPORT.md might be getting written there instead of workspace-main/phase2-routing-test-....

4) Add a “cheap” proof-of-life signal in the mapping while debugging

Temporarily set a super-obvious message template prefix so you can see (in logs and/or chat delivery) that the correct agent got invoked:

messageTemplate: "[DELIVERY_AGENT TEST] card={{cardId}} name={{cardName}} ..."

Optionally set name: "Trello Delivered" in the mapping too — it helps readability in summaries/logs.

#
grep -n "a99cb42f-6268-4553-8c2f-2ef204a37785" /tmp/openclaw/openclaw-*.log | tail -200

That will usually reveal one of:

  • “agentId not allowed” / “unknown agentId, falling back”
  • “failed to load agent workspace”
  • “session store path … must be within sessions directory” (known in some versions)
  • a stack trace from the delivery agent run

4) Temporarily increase file-log detail (best signal)

Set file logs to debug (this affects file logs; --verbose does not):

openclaw config set logging.level debug
#

If you paste the full “Delivered” mapping entry (and your current hooks.allowedAgentIds value), I can tell you the exact openclaw config set ... commands (with correct array indices) so you don’t have to guess which hooks.mappings[N] is which.