{"record":{"id":"e38039ee9b724255","repo":"sipeed/picoclaw","slug":"slack-webhook-webhook-q-must-use-https-got-q","errorCode":null,"errorMessage":"slack_webhook: webhook %q must use HTTPS (got %q)","messagePattern":"slack_webhook: webhook %q must use HTTPS \\(got %q\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/channels/slack_webhook/slack_webhook.go","lineNumber":56,"sourceCode":"\tif len(cfg.Webhooks) == 0 {\n\t\treturn nil, fmt.Errorf(\"slack_webhook: at least one webhook target is required\")\n\t}\n\n\tif _, hasDefault := cfg.Webhooks[\"default\"]; !hasDefault {\n\t\treturn nil, fmt.Errorf(\"slack_webhook: a 'default' webhook target is required\")\n\t}\n\n\tfor name, target := range cfg.Webhooks {\n\t\twebhookURL := target.WebhookURL.String()\n\t\tif webhookURL == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"slack_webhook: webhook %q has empty webhook_url\", name)\n\t\t}\n\t\tparsed, err := url.Parse(webhookURL)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"slack_webhook: webhook %q has invalid URL format: %w\", name, err)\n\t\t}\n\t\tif !strings.EqualFold(parsed.Scheme, \"https\") {\n\t\t\treturn nil, fmt.Errorf(\"slack_webhook: webhook %q must use HTTPS (got %q)\", name, parsed.Scheme)\n\t\t}\n\t}\n\n\tbase := channels.NewBaseChannel(\n\t\t\"slack_webhook\",\n\t\tcfg,\n\t\tbus,\n\t\t[]string{\"*\"},\n\t\tchannels.WithMaxMessageLength(40000),\n\t)\n\n\treturn &SlackWebhookChannel{\n\t\tBaseChannel: base,\n\t\tbc:          bc,\n\t\tconfig:      cfg,\n\t\tclient: &http.Client{\n\t\t\tTimeout: 30 * time.Second,\n\t\t},","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/slack_webhook/slack_webhook.go#L38-L74","documentation":"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.","triggerScenarios":"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://.","commonSituations":"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.","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)."],"exampleFix":"# before\nwebhook_url: \"http://hooks.slack.com/services/T000/B000/abc\"\n\n# after\nwebhook_url: \"https://hooks.slack.com/services/T000/B000/abc\"","handlingStrategy":"validation","validationCode":"func isHTTPSWebhook(raw string) bool {\n    u, err := url.Parse(strings.TrimSpace(raw))\n    return err == nil && strings.EqualFold(u.Scheme, \"https\")\n}","typeGuard":null,"tryCatchPattern":"// Go: construction-time error; the message echoes the offending scheme — fix the URL, no runtime handling","preventionTips":["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"],"tags":["slack-webhook","https","security","config","validation"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}