---
title: Troubleshooting Mastodon Backfeed and Stale Webmentions
description: 'A practical runbook for common failure modes in Mastodon + Bridgy + webmention.io setups: token scopes, canonical URLs, delayed backfeed, and stale reactions that no longer exist upstream.'
pubDate: '2026-03-24T16:05:00+01:00'
category: en/development
tags:
  - indieweb
  - mastodon
  - webmentions
seriesParent: joining-the-indieweb
seriesOrder: 10
---

Automating syndication was the easy part. Getting reaction backfeed and cleanup right — so that likes, reposts, and replies from Mastodon appear on the canonical post and disappear when the source is deleted — needed considerably more care. This is the practical checklist that emerged from debugging real failures.

## The setup

- **Canonical site**: Astro 6 static build at `adrian-altner.de`.
- **Bridge**: Bridgy Fed, mapping Mastodon interactions to canonical URLs via `u-syndication`.
- **Store**: webmention.io, queried at build and from the client for live updates.

## Outside the authorized scopes

**Problem:** Mastodon returns:

```
{"error":"This action is outside the authorized scopes"}
```

The access token is missing required permissions.

**Implementation:** for script-based posting, issue a token with at least:

- `write:statuses`
- `write:media`

Also strip unnecessary API calls that would need extra scopes. Removing a pre-flight `verify_credentials` from the post flow eliminated a class of scope failures that had nothing to do with posting.

## Backfeed not appearing on Bridgy

**Problem:** a common trap — interacting with the syndicated Mastodon post before the site is redeployed with the matching `u-syndication` link. If Bridgy can't map the social interaction back to the canonical page URL, it shows nothing.

**Implementation:** fix order matters.

1. Deploy first so "Shared on Mastodon" is live on the page.
2. Use Bridgy's `Poll now` / `Crawl now`.
3. If still missing, trigger `Resend for post`.
4. Retry the interaction.

**Solution:** the `u-syndication` link has to exist on the canonical page at the moment Bridgy crawls. Any sequence that reverses that ends in silent data loss — the reactions happened, but Bridgy had nowhere to route them.

## Canonical URL mismatch (trailing slash)

webmention.io target matching is exact. `.../hello-world` and `.../hello-world/` are different targets.

When debugging, always test with the canonical URL as it appears on the page — including trailing slash — otherwise you can easily read an empty result and chase the wrong bug for an hour.

## 429 Too many requests on media uploads

**Problem:** large backfills saturate media API limits fast.

**Implementation:** the syndication script now retries media uploads with backoff and honours `Retry-After` when the server sends it. Status posting continues even if a media upload ultimately fails, so the text post goes out and backfill progress isn't blocked by images.

## Deleted likes/reposts still visible

The most annoying failure mode. Deletions don't always propagate cleanly through every layer — webmention.io can still hold the old reaction record, and the source URL may still return HTTP 200 even when the interaction itself is gone upstream.

**Implementation:** source re-validation at interaction level, not just URL existence:

- **Mastodon** — validate `favorited-by` / `reblogged-by` against the status's interaction APIs.
- **Bluesky** — validate `liked_by` / `reposted_by` against the public API lists.
- **Replies** — validate source post existence directly via the platform APIs.

**Solution:** if the upstream interaction or source post is gone, it's filtered out automatically at render time — no manual dashboard surgery required.

## Client refresh not removing stale UI

**Problem:** even with correct filtering server-side, the UI can stay stale if the client refresh only handles additions.

**Implementation:** the webmentions component now tracks the current count and re-renders on both directions:

- new mentions added
- existing mentions removed

**Solution:** deletions become visible without having to manually prune in the webmention.io dashboard.

## A practical debugging order

When something looks wrong, this order cuts through the noise:

1. Verify the canonical target URL — including trailing slash.
2. Inspect filtered local endpoint output.
3. Check source interaction / post existence upstream.
4. Trigger Bridgy poll / crawl.
5. Only then touch manual dashboard deletion.

Most "it still shows" issues are one of those five, not a rendering bug.

## What to take away

- **Token scopes are the first thing to check.** `write:statuses` and `write:media` are the minimum; cut any pre-flight calls that need more.
- **Deploy before interacting.** Bridgy needs the `u-syndication` link on the canonical page at crawl time, not later.
- **Trailing slashes are load-bearing.** Treat them as part of the identifier everywhere — webmention.io, state files, component queries.
- **Re-validate upstream interactions, not just URLs.** A source URL can return 200 long after the like itself is gone — only the interaction API tells the truth.
- **Client refresh must handle both directions.** Additions and removals, otherwise deleted reactions linger in the UI forever.
