Significant-Gravitas/AutoGPT · warning · NotFoundError

Webhook #{webhook_id} not found

Error message

Webhook #{webhook_id} not found

What it means

Raised by the webhook ingress endpoint (POST /integrations/{provider}/webhooks/{webhook_id}/webhook) when no webhook with the given ID exists in the database, or deliberately when the webhook exists but its registered provider does not match the provider in the URL. The identical 404 for both cases conceals which webhook IDs exist, preventing enumeration. It surfaces as HTTP 404 with detail 'Webhook #{webhook_id} not found'.

Source

Thrown at autogpt_platform/backend/backend/api/features/integrations/router.py:706

    provider: Annotated[
        ProviderName, Path(title="Provider where the webhook was registered")
    ],
    webhook_id: Annotated[str, Path(title="Our ID for the webhook")],
):
    logger.debug(f"Received {provider.value} webhook ingress for ID {webhook_id}")
    webhook_manager = get_webhook_manager(provider)
    try:
        webhook = await get_webhook(webhook_id, include_relations=True)
        # Sanity check: `provider` from URL and fetched webhook must match.
        # Otherwise the URL provider's verifier runs instead of the webhook's
        # own (a no-op for unsigned providers like Compass), bypassing it.
        if webhook.provider.value.lower() != provider.value.lower():
            logger.warning(
                f"Webhook #{webhook_id} provider mismatch: "
                f"registered as {webhook.provider.value}, ingress via {provider.value}"
            )
            # Same as the actual "webhook not found" response to conceal existence
            raise NotFoundError(f"Webhook #{webhook_id} not found")
    except NotFoundError as e:
        logger.warning(f"Webhook payload received for unknown webhook #{webhook_id}")
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
    logger.debug(f"Webhook #{webhook_id}: {webhook}")

    user_id = webhook.user_id
    try:
        credentials = (
            await creds_manager.get(user_id, webhook.credentials_id)
            if webhook.credentials_id
            else None
        )
    except NotFoundError as e:
        logger.warning(f"Webhook payload received for unknown webhook #{webhook_id}")
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))

    # Run provider signature verification (no-op for providers whose protocol
    # has no signing scheme). 403 on failure; not 404 — that would leak

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Verify the webhook still exists: GET /integrations/webhooks (list webhooks for the user) and confirm the ID and its provider field.
  2. Check the provider segment of the ingress URL matches the webhook's registered provider exactly (the check is case-insensitive on provider value).
  3. If the webhook was pruned, re-register it via the provider block or POST /integrations/{provider}/webhooks and update the URL configured at the provider.
  4. If you control the sender, stop retrying on 404 — the resource is gone and retries will never succeed.

Example fix

# before: sending event via wrong provider path
POST /integrations/github/webhooks/9d2f.../webhook  # webhook is registered under 'compass'

# after: match the webhook's registered provider
POST /integrations/compass/webhooks/9d2f.../webhook
Defensive patterns

Strategy: validation

Validate before calling

# Before relying on an ingress URL, confirm the webhook exists and provider matches
webhooks = await client.get("/integrations/webhooks")
wh = next((w for w in webhooks.json() if w["id"] == webhook_id), None)
if wh is None or wh["provider"].lower() != provider.lower():
    re_register_webhook(provider)  # stale URL — rebuild it before the provider sends events

Try / catch

# Ingress endpoints are called by providers, not your code — do not retry 404.
# If you proxy ingress, classify:
if resp.status_code == 404:
    disable_webhook_url(webhook_id)  # terminal: webhook gone or provider mismatch
elif resp.status_code == 403:
    alert_signature_problem(webhook_id)

Prevention

When it happens

Trigger: POSTing a webhook event to a URL whose webhook_id was deleted or pruned (dangling webhooks are pruned when credentials are removed), replaying an old URL after re-registering the webhook, or sending the event through the wrong provider segment of the URL (e.g. hitting /integrations/github/webhooks/{id}/webhook for a webhook registered under compass), which triggers the provider-mismatch sanity check that intentionally returns this same 404.

Common situations: Provider removed the webhook on their side and a queued event still arrives after AutoGPT pruned it; developer copied the ingress URL with the wrong provider name; webhook was auto-pruned because its credentials were deleted; stale hardcoded URL in a test suite after the webhook table was reset.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/b4d8c1fcad8c27ed. Report an issue: GitHub.