Callback URL is built from LISTEN_ADDR instead of a public callback base URL #1

Closed
opened 2026-04-27 18:37:41 +07:00 by codex · 2 comments
Collaborator

Summary

callback_url is currently derived from LISTEN_ADDR, which is the local bind address of the HTTP server, not a public URL that OpenClaw can call back to.

Evidence

  • internal/ai_client/client.go:68 builds the callback as http://<LISTEN_ADDR>/callback
  • internal/config/config.go:72-74 defaults LISTEN_ADDR to :8080
  • cmd/bridge/main.go:68-69 also uses LISTEN_ADDR as the server bind address
  • requirements.md:81-86 requires dispatch payload to include callback_url

Why this is a problem

  • With the default config, the generated callback URL becomes http://:8080/callback, which is not a usable external URL.
  • In common deployments the service binds to :8080 or 0.0.0.0:8080, but OpenClaw needs a public hostname/URL to reach the callback.
  • Reusing the same variable for both bind address and advertised callback URL makes reverse-proxy or tunnel deployments impossible without code changes.

Expected behavior

  • Keep LISTEN_ADDR only for local server binding.
  • Add a separate config value for the public callback base URL and use that when generating callback_url.

Impact

End-to-end dispatch can succeed while the callback never reaches the bridge in real deployments.

## Summary `callback_url` is currently derived from `LISTEN_ADDR`, which is the local bind address of the HTTP server, not a public URL that OpenClaw can call back to. ## Evidence - `internal/ai_client/client.go:68` builds the callback as `http://<LISTEN_ADDR>/callback` - `internal/config/config.go:72-74` defaults `LISTEN_ADDR` to `:8080` - `cmd/bridge/main.go:68-69` also uses `LISTEN_ADDR` as the server bind address - `requirements.md:81-86` requires dispatch payload to include `callback_url` ## Why this is a problem - With the default config, the generated callback URL becomes `http://:8080/callback`, which is not a usable external URL. - In common deployments the service binds to `:8080` or `0.0.0.0:8080`, but OpenClaw needs a public hostname/URL to reach the callback. - Reusing the same variable for both bind address and advertised callback URL makes reverse-proxy or tunnel deployments impossible without code changes. ## Expected behavior - Keep `LISTEN_ADDR` only for local server binding. - Add a separate config value for the public callback base URL and use that when generating `callback_url`. ## Impact End-to-end dispatch can succeed while the callback never reaches the bridge in real deployments.
Collaborator

Implementation plan

Agreed direction: separate bind address from callback URL generation.

Scope

  • Keep LISTEN_ADDR for HTTP bind only.
  • Add CALLBACK_BASE_URL for dispatch payload callback URL.
  • If CALLBACK_BASE_URL is unset, default to http://localhost.

Steps

  1. Config update + tests

    • Add CallbackBaseURL to config.
    • Read from env CALLBACK_BASE_URL.
    • Default to http://localhost when empty.
    • Add unit tests in internal/config/config_test.go.
  2. Dispatcher update + tests

    • Replace callback generation from LISTEN_ADDR with callback base URL.
    • Add helper to normalize trailing slash and append /callback.
    • Add unit tests in internal/ai_client/client_test.go.
  3. Docs/env update

    • Update .env.example and README:
      • LISTEN_ADDR = local bind only.
      • CALLBACK_BASE_URL = public callback base, localhost fallback.
  4. Verification

    • go test ./internal/config -run CallbackBaseURL -v
    • go test ./internal/ai_client -run BuildCallbackURL -v
    • go test ./...

Tracking

  • Full detailed execution plan is saved at:
    docs/superpowers/plans/2026-04-27-callback-base-url.md
## Implementation plan Agreed direction: separate bind address from callback URL generation. ### Scope - Keep `LISTEN_ADDR` for HTTP bind only. - Add `CALLBACK_BASE_URL` for dispatch payload callback URL. - If `CALLBACK_BASE_URL` is unset, default to `http://localhost`. ### Steps 1. **Config update + tests** - Add `CallbackBaseURL` to config. - Read from env `CALLBACK_BASE_URL`. - Default to `http://localhost` when empty. - Add unit tests in `internal/config/config_test.go`. 2. **Dispatcher update + tests** - Replace callback generation from `LISTEN_ADDR` with callback base URL. - Add helper to normalize trailing slash and append `/callback`. - Add unit tests in `internal/ai_client/client_test.go`. 3. **Docs/env update** - Update `.env.example` and README: - `LISTEN_ADDR` = local bind only. - `CALLBACK_BASE_URL` = public callback base, localhost fallback. 4. **Verification** - `go test ./internal/config -run CallbackBaseURL -v` - `go test ./internal/ai_client -run BuildCallbackURL -v` - `go test ./...` ### Tracking - Full detailed execution plan is saved at: `docs/superpowers/plans/2026-04-27-callback-base-url.md`
Owner

closed by #6

closed by #6
Sign in to join this conversation.
No labels
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: thuanle/claw-email#1