Skip to content

fix nil pointer deref for ErrAccountRepoNotFound - #1142

Merged
bnewbold merged 1 commit into
bluesky-social:mainfrom
uniphil:fix/relay/listrepos-nil-deref
Aug 28, 2025
Merged

fix nil pointer deref for ErrAccountRepoNotFound#1142
bnewbold merged 1 commit into
bluesky-social:mainfrom
uniphil:fix/relay/listrepos-nil-deref

Conversation

@uniphil

@uniphil uniphil commented Aug 28, 2025

Copy link
Copy Markdown
Contributor

this change just makes sure repo is not nil before we try to pull a Rev out of it.

assigning the Rev from the repo follows what's almost a boilerplate golang error handler, but is sneakily not handling relay.ErrAccountRepoNotFound -- seems the intent is to provide a happy-path response for a common error case.

unfortunately the Rev assignment tried to dereference that from repo unconditionally, so it panicked in the allowed-error path.

(still need to test and will verify on my relays)

this change just makes sure `repo` is not nil before we try to pull a `Rev` out of it.

assigning the Rev from the repo follows what's *almost* a boilerplate golang error handler, but is sneakily not handling relay.ErrAccountRepoNotFound -- seems the intent is to provide a happy-path response for a common error case.

unfortunately the Rev assignment tried to dereference that unconditionally, so it panicked in the allowed-error path.
@uniphil

uniphil commented Aug 28, 2025

Copy link
Copy Markdown
Contributor Author

i wonder if the relay should actually just fail the request if the GetAccountRepo fails though?

eg. listRepos fails in the same scenario, and gives a response with

"failed to get repo root for (did:plc:rk2yj5gh553zl7uvwilsro66): repository state not available"

https://relay3.fr.hose.cam/xrpc/com.atproto.sync.listRepos?limit=1000&cursor=14489

see it ^^

(bsky relays have the message hidden because of rainbow)

(but also listRepos proabably shouldn't fail the whole request, i'm working on that separately)

@uniphil
uniphil marked this pull request as ready for review August 28, 2025 18:33
@uniphil

uniphil commented Aug 28, 2025

Copy link
Copy Markdown
Contributor Author

ok, tested and confirmed this fix at relay3.fire.hose.cam

  • did:plc:r47ixofywwpyonnqd5d4pmaz is an affected DID
  • bsky us-east relay: panics
  • microcosm montreal relay: panics (unpatched, confirms repro)
  • microcosm france relay: does not panic (has this patch)

it seems like there is another underlying problem here affecting the relays that makes all indigo/cmd/relay relays have trouble with that DID, but i haven't investigated that yet. the upstream pds (matsutake) has a rev and everything: https://matsutake.us-west.host.bsky.network/xrpc/com.atproto.sync.getRepoStatus?did=did:plc:r47ixofywwpyonnqd5d4pmaz

in any case, at least it doesn't panic with this, but it also doesn't indicate that there's any problem. if the relay should fail the request instead, i can follow up with a change to do that instead.

@bnewbold bnewbold left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

thanks! sloppy on my part, though feels like static analysis could have caught this one 🤔

I checked and the rev field is optional under the getRepoStatus lexicon; the text says:

Optional field, the current rev of the repo, if active=true

So in theory if active=false we maybe shouldn't return the rev. I'm not sure if we should update the schema/description to have have that behavior, or update the code to not return the rev in that case (could also skip looking up repo status if active=false).

listRepos is different because rev is required in the response. that should probably be changed in the spec... it breaks the lexicon evolution rules but is the kind of change I think we should still consider as the overall protocol is not 100% baked/stabilized yet.

Regardless, I think this PR is a strict improvement on the current situation so going to merge.

@bnewbold
bnewbold merged commit f4a8398 into bluesky-social:main Aug 28, 2025
2 checks passed
@bnewbold

Copy link
Copy Markdown
Collaborator

as a note, hands are full right now and it will probably be a while before this gets deployed to our relay instances.

created an issue with follow-ups: #1143

@uniphil

uniphil commented Aug 28, 2025

Copy link
Copy Markdown
Contributor Author

edit: moved to the new issue

bnewbold added a commit that referenced this pull request Aug 28, 2025
…unt_repo (#1144)

Accounts sometimes don't have an entry in their account_repo extension
table. This change handles that case for listRepos by including them in
the response but with empty strings for the "Rev" and "Head" fields.

...which probably isn't ultimately correct, but is at least more usable
for clients than missing an entire page of repos because one of them was
affected by this.

placeholder improvement directly related to
#1143

basically the same as #1142 but that PR only addressed getRepoStatus

---

for what it's worth, the sql join `TODO` suggested in the code here
would have hidden (fixed?) this problem by omitting the affected
accounts, assuming inner-join
blackmichael pushed a commit that referenced this pull request Jun 16, 2026
this change just makes sure `repo` is not nil before we try to pull a
`Rev` out of it.

assigning the Rev from the repo follows what's *almost* a boilerplate
golang error handler, but is sneakily not handling
`relay.ErrAccountRepoNotFound` -- seems the intent is to provide a
happy-path response for a common error case.

unfortunately the Rev assignment tried to dereference that from `repo`
unconditionally, so it panicked in the allowed-error path.


(still need to test and will verify on my relays)
blackmichael pushed a commit that referenced this pull request Jun 16, 2026
…unt_repo (#1144)

Accounts sometimes don't have an entry in their account_repo extension
table. This change handles that case for listRepos by including them in
the response but with empty strings for the "Rev" and "Head" fields.

...which probably isn't ultimately correct, but is at least more usable
for clients than missing an entire page of repos because one of them was
affected by this.

placeholder improvement directly related to
#1143

basically the same as #1142 but that PR only addressed getRepoStatus

---

for what it's worth, the sql join `TODO` suggested in the code here
would have hidden (fixed?) this problem by omitting the affected
accounts, assuming inner-join
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants