bytebase/bytebase · error

failed to construct webhook POST request to %s

Error message

failed to construct webhook POST request to %s

What it means

This error wraps an http.NewRequest failure while constructing the POST request to the configured Discord webhook URL. It fires when the request cannot be built at all — most commonly a URL that fails http.NewRequest's parsing (control characters) or an unsupported scheme.

Source

Thrown at backend/plugin/webhook/discord/discord.go:101

	}
	if context.ActorName != "" {
		embed.Author = &WebhookEmbedAuthor{
			Name: fmt.Sprintf("%s (%s)", context.ActorName, context.ActorEmail),
		}
	}
	embedList = append(embedList, embed)

	post := Webhook{
		EmbedList: embedList,
	}
	body, err := json.Marshal(post)
	if err != nil {
		return errors.Wrapf(err, "failed to marshal webhook POST request to %s", context.URL)
	}
	req, err := http.NewRequest("POST",
		context.URL, bytes.NewBuffer(body))
	if err != nil {
		return errors.Wrapf(err, "failed to construct webhook POST request to %s", context.URL)
	}

	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{
		Timeout: webhook.Timeout,
	}
	resp, err := client.Do(req)
	if err != nil {
		return errors.Wrapf(err, "failed to POST webhook to %s", context.URL)
	}

	b, err := io.ReadAll(resp.Body)
	if err != nil {
		return errors.Wrapf(err, "failed to read POST webhook response from %s", context.URL)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {

View on GitHub (pinned to 1870550677)

Solutions

  1. Check the configured webhook URL for stray whitespace, newlines, or quotes and correct it in IM settings.
  2. Validate the URL with url.Parse before saving the webhook configuration.
  3. Re-copy the Discord webhook URL from Discord's integration UI.

Example fix

// before
if err != nil {
  return errors.Wrapf(err, "failed to construct webhook POST request to %s", context.URL)
}
// after (caller-side guard before configuring)
u, err := url.Parse(strings.TrimSpace(webhookURL))
if err != nil || u.Scheme != "https" || !strings.Contains(u.Host, "discord.com") {
  return fmt.Errorf("invalid discord webhook url %q", webhookURL)
}
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(strings.TrimSpace(webhookURL))
if err != nil || u.Scheme != "https" || u.Host == "" {
  return fmt.Errorf("invalid discord webhook url")
}
if !strings.HasPrefix(u.Path, "/api/webhooks/") {
  return fmt.Errorf("not a discord webhook url")
}

Type guard

func isDiscordWebhookURL(raw string) bool {
  u, err := url.Parse(strings.TrimSpace(raw))
  return err == nil && u.Scheme == "https" && strings.HasPrefix(u.Host, "discord.com") && strings.HasPrefix(u.Path, "/api/webhooks/")
}

Try / catch

if err := discord.Post(ctx, whCtx); err != nil {
  if strings.Contains(err.Error(), "construct") {
    return fmt.Errorf("webhook URL invalid, re-configure: %w", err)
  }
  return err
}

Prevention

When it happens

Trigger: http.NewRequest("POST", context.URL, ...) returns an error, typically because the stored webhook URL is malformed (whitespace/control characters) rather than merely unparseable scheme.

Common situations: An IM setting URL pasted with trailing newline/space, quotes, or corrupted by a bad migration; a misconfigured base URL in deployment config.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/e0330b1ab81b6bb7. Report an issue: GitHub.