Skip to content

PDS: Read-after-write profile munging preserves stale upstream postsCount after local writes #164

@aliceisjustplaying

Description

@aliceisjustplaying

Uncovered while testing https://github.com/aliceisjustplaying/atproto-smoke against rsky-pds

This is one I'm not 100% confident about but confident enough to report it and worth investigating.


Describe the bug

After com.atproto.repo.createRecord, the local read-after-write path is inconsistent:

  • app.bsky.feed.getAuthorFeed immediately includes the new post
  • app.bsky.actor.getProfile still returns stale postsCount
  • app.bsky.actor.getProfiles can time out in that window, and later still return stale postsCount

This causes a real client-visible failure: on bsky.app, post -> own profile can land on the correct profile URL but render only the shell/footer with no profile content. The same
sequence works against bluesky-pds on the same VPS.

To Reproduce

Steps to reproduce the behavior:

  1. Log into https://bsky.app against https://rsky.pdslab.net
  2. Create a post
  3. Immediately navigate to /profile/<own-handle>
  4. Observe that the page lands on the correct profile URL but the profile content never appears
  5. Compare with bluesky-pds, where the same flow works

Expected behavior

After a local write, profile reads should reflect the updated local state consistently enough for bsky.app to render the profile page correctly.

Details

  • Operating system: Linux 6.12.63+deb13-arm64 aarch64 GNU/Linux
  • Node version: v20.19.2

Additional context

  • Tested version: main at d2cb2b4e695a6f25b5981cab21eb6c7621fe4de8
  • Rust: rustc 1.94.0 (4a4ef493e 2026-03-02)
  • Direct local XRPC trace:
    • createRecord: 200 fast
    • getAuthorFeed: 200, includes the new post immediately
    • getProfile: 200, but stale postsCount
    • getProfiles: can time out immediately after the write; later returns 200 but still stale postsCount
  • Files:
  • Exact code detail:
    • get_profile_munge() and get_profiles_munge() call local_viewer.update_profile_detailed(...)
    • update_profile_detailed preserves followers_count, follows_count, and posts_count from the original upstream view unchanged,
      while only overlaying profile-record fields like display_name, description, avatar, and banner
  • Minimal fix:
    Make read-after-write profile munging patch derived profile counters from local records instead of preserving stale upstream counts unchanged. The likely change is in
    update_profile_detailed and the get_profile_munge / get_profiles_munge call sites.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions