sipeed/picoclaw · error
slack_webhook: webhook %q must use HTTPS (got %q)
Error message
slack_webhook: webhook %q must use HTTPS (got %q)
What it means
NewSlackWebhookChannel enforces that every webhook_url uses the https scheme (case-insensitive via strings.EqualFold). Slack incoming webhooks are only served over HTTPS; an http:// URL is rejected at construction. This is also a data-protection guard: webhook URLs are bearer secrets, and sending them over plain HTTP would leak them.
Source
Thrown at pkg/channels/slack_webhook/slack_webhook.go:56
if len(cfg.Webhooks) == 0 {
return nil, fmt.Errorf("slack_webhook: at least one webhook target is required")
}
if _, hasDefault := cfg.Webhooks["default"]; !hasDefault {
return nil, fmt.Errorf("slack_webhook: a 'default' webhook target is required")
}
for name, target := range cfg.Webhooks {
webhookURL := target.WebhookURL.String()
if webhookURL == "" {
return nil, fmt.Errorf("slack_webhook: webhook %q has empty webhook_url", name)
}
parsed, err := url.Parse(webhookURL)
if err != nil {
return nil, fmt.Errorf("slack_webhook: webhook %q has invalid URL format: %w", name, err)
}
if !strings.EqualFold(parsed.Scheme, "https") {
return nil, fmt.Errorf("slack_webhook: webhook %q must use HTTPS (got %q)", name, parsed.Scheme)
}
}
base := channels.NewBaseChannel(
"slack_webhook",
cfg,
bus,
[]string{"*"},
channels.WithMaxMessageLength(40000),
)
return &SlackWebhookChannel{
BaseChannel: base,
bc: bc,
config: cfg,
client: &http.Client{
Timeout: 30 * time.Second,
},View on GitHub (pinned to 49183d7e8d)
Solutions
- Use the exact https://hooks.slack.com/services/... URL Slack shows for the incoming webhook.
- If routing through an internal proxy, terminate TLS before the proxy and still configure the https:// form.
- Add the scheme when it is missing: https://hooks.slack.com/... — the error message echoes the scheme it saw (empty means no scheme).
Example fix
# before webhook_url: "http://hooks.slack.com/services/T000/B000/abc" # after webhook_url: "https://hooks.slack.com/services/T000/B000/abc"
Defensive patterns
Strategy: validation
Validate before calling
func isHTTPSWebhook(raw string) bool {
u, err := url.Parse(strings.TrimSpace(raw))
return err == nil && strings.EqualFold(u.Scheme, "https")
} Try / catch
// Go: construction-time error; the message echoes the offending scheme — fix the URL, no runtime handling
Prevention
- Only ever store https://hooks.slack.com/services/... URLs
- webhook URLs are bearer secrets — https is also a secrecy requirement
- Beware scheme-less pastes: 'hooks.slack.com/...' fails with an empty scheme
When it happens
Trigger: webhook_url starting with http:// (including Http:// variants — EqualFold is case-insensitive but only https passes); a URL missing its scheme entirely ("hooks.slack.com/services/...") parses with an empty scheme and also fails; internal proxy URLs configured with http://.
Common situations: Copying an http:// link from old documentation or a chat message; hand-typing the URL and omitting the scheme or the s; pointing at an internal HTTPS-terminating proxy and forgetting to update the scheme after enabling TLS; misconfigured copy of the Slack URL from a legacy integration page.
Related errors
- slack_webhook: a 'default' webhook target is required
- slack_webhook: webhook %q has empty webhook_url
- slack_webhook: webhook %q has invalid URL format: %w
- ${label} must be a JSON object.
- ${label}.${key} must be a string.
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/e38039ee9b724255.
Report an issue: GitHub.