Significant-Gravitas/AutoGPT · warning · HTTPException

Webhook not found

Error message

Webhook not found

What it means

POST /integrations/webhooks/{webhook_id}/ping requires auth (get_user_id). It fetches the webhook and, if webhook.user_id differs from the authenticated caller, returns HTTP 404 'Webhook not found' rather than 403. Treating webhooks you don't own as nonexistent prevents using this endpoint to enumerate webhook IDs or ping other users' webhooks. A genuinely missing webhook produces the same response via get_webhook's NotFoundError path.

Source

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

            preset, webhook, webhook_id, event_type, payload
        )
        for preset in webhook.triggered_presets
    )

    if tasks:
        await asyncio.gather(*tasks, return_exceptions=True)


@router.post("/webhooks/{webhook_id}/ping")
async def webhook_ping(
    webhook_id: Annotated[str, Path(title="Our ID for the webhook")],
    user_id: Annotated[str, Security(get_user_id)],  # require auth
):
    webhook = await get_webhook(webhook_id)
    if webhook.user_id != user_id:
        # Treat a webhook the caller doesn't own as if it doesn't exist, so this
        # endpoint can't be used to enumerate webhook IDs or ping others' webhooks.
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Webhook not found"
        )
    webhook_manager = get_webhook_manager(webhook.provider)

    credentials = (
        await creds_manager.get(user_id, webhook.credentials_id)
        if webhook.credentials_id
        else None
    )
    try:
        await webhook_manager.trigger_ping(webhook, credentials)
    except NotImplementedError:
        return False

    if not await wait_for_webhook_event(webhook_id, event_type="ping", timeout=10):
        raise HTTPException(
            status_code=status.HTTP_504_GATEWAY_TIMEOUT, detail="Webhook ping timed out"
        )

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. List your own webhooks (GET /integrations/webhooks) and use an ID from that list — those are guaranteed owned by the authenticated user.
  2. Verify the auth token you're sending belongs to the user who registered the webhook.
  3. If the webhook was registered by another user, have that user ping it or re-register your own.
  4. If testing cross-user flows is intentional, re-register the webhook under the test user instead of reusing an ID.
Defensive patterns

Strategy: validation

Validate before calling

# Only ping webhooks owned by the authenticated user
owned = {w["id"] for w in (await client.get("/integrations/webhooks")).json()}
if webhook_id not in owned:
    skip_ping(webhook_id)  # 404 by design for foreign/missing IDs

Prevention

When it happens

Trigger: Calling ping with a webhook_id owned by another user; using a JWT from user A while the webhook was registered by user B (e.g. admin tooling or a shared test suite hitting a production DB); a webhook_id that was deleted or never existed.

Common situations: Team environments where a teammate registered the webhook and you copied its ID into your script; expired Supabase session pointing at a different user than expected; copy-paste of webhook IDs between environments (dev URL + prod ID).

Related errors


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