Skip to content

check_followed_severity crashes with 400 "start_at" error because fetch_instance_follows omits required params on /api/v1/admin/measures #79

Description

@barik

Describe the bug
When max_followed_severity is configured on a blocklist_instance_destinations entry to a value lower than the severity of an incoming block (e.g. silence while pushing suspend blocks), push_blocklist calls check_followed_severity, which in turn calls fetch_instance_follows (fediblockhole/init.py). That function POSTs to the target instance's /api/v1/admin/measures endpoint with only keys and the per-key filter:

data = {
    "keys": [key],            # key = "instance_follows"
    key: {"domain": domain},
}
response = requests.post(url, headers=requests_headers(token), json=data, timeout=REQUEST_TIMEOUT)

Mastodon's admin measures API requires top-level start_at and end_at parameters on every call. Since they're never sent, the target instance returns 400 Bad Request, and fetch_instance_follows raises an unhandled ValueError, crashing the entire sync run — including any blocks that hadn't been pushed yet.

To Reproduce

  1. Configure a blocklist_instance_destinations entry with max_followed_severity = 'silence' (or any value lower than suspend).
  2. Configure a blocklist_url_sources or blocklist_instance_sources entry that will produce at least one suspend-severity block.
  3. Run fediblock-sync.
  4. Observe a crash on the first block that exceeds max_followed_severity:
    ValueError: Something went wrong: 400: b'{"error":"param is missing or the value is empty or invalid: start_at"}'
    

Expected behaviour
fetch_instance_follows should include valid start_at/end_at values in the request body (per the Mastodon admin measures API), so the follows check succeeds instead of raising, and the sync should not abort the whole run on a single failed follows-check.

Environment

  • OS/Distribution: Linux (Docker, mirror.gcr.io/library/python)
  • Python version: 3.14
  • fediblockhole version: 0.4.6 (bug also present in 0.4.5)
  • Mastodon version: 4.6.4 (rejects requests missing start_at)

Additional context
Confirmed by reading fetch_instance_follows and check_followed_severity in both the 0.4.6 and 0.4.5 releases on PyPI — the missing start_at/end_at params are present in both, so this isn't a recent regression, just a latent bug that's only triggered when max_followed_severity causes the follows-check path to actually run. As a workaround, setting max_followed_severity equal to the highest severity in use ('suspend') avoids the code path entirely, at the cost of losing the "don't suspend domains our users still follow" protection.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions