Skip to content

Conversation

@obenland
Copy link
Member

@obenland obenland commented Oct 25, 2025

Fixes #2366, the infinite recursion bug that fills error logs when storing remote actors with @mentions in their bios.

Proposed changes:

  • Temporarily remove mention/hashtag/link filters when storing remote actors to prevent infinite recursion
  • Add comprehensive tests for self-mention and cross-mention scenarios
  • Document the problem, current approach, shortcomings, and long-term architectural solutions in code comments

The Problem

When a remote actor's bio contains mentions (e.g., @[email protected]), the mention processing filter fetches that mentioned actor, which then processes mentions in their bio, creating an infinite loop that results in stack overflow errors.

The Solution

In Remote_Actors::prepare_custom_post_type(), temporarily remove the activitypub_activity_object_array filters (Mention, Hashtag, Link) around to_json(), then re-add them. This prevents filters from triggering during storage while preserving functionality for outgoing federation.

Other information:

  • Have you written new tests for your changes, if applicable?
    • Added test_create_actor_with_self_mention_no_recursion
    • Added test_create_actor_with_cross_mentions_no_recursion

Testing instructions:

  • Run the new recursion tests: npm run env-test -- --filter=test_create_actor_with
  • Verify both tests pass
  • Run the full test suite: npm run env-test
  • Verify all 1217 tests pass

Changelog entry

  • Automatically create a changelog entry from the details below.
Changelog Entry Details

Significance

  • Patch

Type

  • Fixed - for any bug fixes

Message

Fix infinite recursion when storing remote actors with mentions in their bios

When storing remote actors with @mentions in their bios, the mention
processing filter would fetch the mentioned actor, which would then
process mentions in their bio, creating an infinite loop that fills
error logs and crashes with stack overflow.

The fix temporarily removes mention/hashtag/link filters around the
to_json() call when storing remote actors, then re-adds them afterward.

Added comprehensive tests that reproduce the recursion scenario:
- Self-mention: actor mentioning themselves in their bio
- Cross-mention: two actors mentioning each other

The code includes detailed comments documenting this approach's
shortcomings and exploring better long-term solutions that distinguish
between incoming (storage) and outgoing (federation) contexts.
@Copilot Copilot AI review requested due to automatic review settings October 25, 2025 01:05
@obenland obenland self-assigned this Oct 25, 2025
@obenland obenland requested a review from pfefferle October 25, 2025 01:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an infinite recursion bug that occurs when storing remote actors whose bios contain mentions. The recursion happens because mention processing filters attempt to fetch mentioned actors, which then trigger mention processing on those actors' bios, creating a loop.

Key Changes:

  • Temporarily removes mention/hashtag/link filters during Remote_Actors::prepare_custom_post_type() execution to prevent recursion
  • Adds comprehensive test coverage for self-mention and cross-mention scenarios
  • Documents the problem, current approach, limitations, and proposed long-term architectural improvements

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
includes/collection/class-remote-actors.php Implements filter removal/re-addition around to_json() call to prevent recursive mention processing during actor storage
tests/phpunit/tests/includes/collection/class-test-remote-actors.php Adds two new test cases verifying no recursion occurs with self-mentions and cross-mentions in actor bios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Instead of using remove_all_filters() which could interfere with other
tests, extract filter callbacks into variables and remove them
individually using remove_filter().

This ensures only the filters added by these specific tests are
removed during cleanup, preventing interference with filters from
other test sources.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Possible Infinite Recursion bug?

2 participants