[bug] Broken federation with WriteFreely (and probably other platforms) #963

Closed
opened 2025-08-04 00:52:54 +00:00 by blacklight · 1 comment

Your setup

OTP

Extra details

Arch Linux

Version

3.15.2

PostgreSQL version

17.5

What were you trying to do?

Summary

When federating an ActivityPub Update activity from WriteFreely (and similar platforms), Akkoma/Pleroma crashes with the following error:

(KeyError) key :data not found in: nil
lib/pleroma/web/activity_pub/side_effects.ex:428: Pleroma.Web.ActivityPub.SideEffects.handle_update_object/2
...

Steps to Reproduce

  1. Receive an ActivityPub Update activity from a remote server, where:
    • The activity has "type": "Update"
    • The object is a standard Note (or Article) with valid fields: id, type, content, published, url, etc.
    • Example payload:
      {
        "@context": ["https://www.w3.org/ns/activitystreams"],
        "type": "Update",
        "id": "https://remote-server/api/posts/abcd1234",
        "actor": "https://remote-server/api/collections/user",
        "published": "2025-08-03T21:57:57+02:00",
        "updated": "2025-08-04T01:53:18+02:00",
        "object": {
          "type": "Note",
          "id": "https://remote-server/api/posts/abcd1234",
          "published": "2025-08-03T21:57:57+02:00",
          "updated": "2025-08-04T01:53:18+02:00",
          "url": "https://remote-server/render-your-jupyter-notebooks-in-opengist",
          "attributedTo": "https://remote-server/api/collections/user",
          "to": ["https://www.w3.org/ns/activitystreams#Public"],
          "cc": ["https://my-instance/users/me"],
          "name": "Title",
          "content": "<p>Some HTML post content</p>",
          "attachment": [
            {
              "type": "Document",
              "url": "https://remote-server/img.png",
              "mediaType": "image/png"
            }
          ]
        }
      }
      
  2. Observe that the instance crashes and rejects the Update.

Additional Notes

  • The same Update payload is accepted by Mastodon and other AP servers.
  • The crash appears to be a bug in the handling of Update activities for unknown objects.
  • The error log references side_effects.ex and the use of .data on a nil value.

How to reproduce from scratch

  1. Set up a remote AP server (WriteFreely, etc.).
  2. Federate a post (Update activity) referencing an object ID not yet present on Akkoma.
  3. Observe crash.

Proposed Fix

  • Update should be handled gracefully if the object does not exist.
  • Do not crash the worker; return a 4xx error or log the rejection.

What did you expect to happen?

Akkoma/Pleroma should either:

  • Accept the Update if the referenced object exists.
  • Gracefully reject the Update if the object does not exist (with an error response), but should not crash.

What actually happened?

  • The instance crashes with (KeyError) key :data not found in: nil.
  • This appears to happen if the Update refers to an object that was never created (never received a "Create" for that ID).

Logs

```
01:53:20.009 [error] Receiver worker CRASH on %{"@context" => ["https://www.w3.org/ns/activitystreams"], "actor" => "https://write.example.com/api/collections/fabio", "id" => "https://write.example.com/api/posts/d1e390ocd3", "object" => %{"attachment" => [%{"mediaType" => "image/png", "name" => "", "type" => "Document", "url" => "https://s3.example.com/fabio/img/gist-ipynb-screenshot-small.png"}, %{"mediaType" => "image/png", "name" => "", "type" => "Document", "url" => "https://s3.example.com/fabio/img/gist-ipynb-screenshot.png"}, %{"mediaType" => "image/png", "name" => "", "type" => "Document", "url" => "https://s3.example.com/fabio/img/gist-ipynb-screenshot-small.png"}, %{"mediaType" => "image/png", "name" => "", "type" => "Document", "url" => "https://s3.example.com/fabio/img/gist-ipynb-screenshot.png"}], "attributedTo" => "https://write.example.com/api/collections/fabio", "cc" => ["https://example.social/users/fabio"], "content" => "....", "id" => "https://write.example.com/api/posts/d1e390ocd3", "name" => "Render your Jupyter notebooks in OpenGist", "published" => "2025-08-03T21:57:57+02:00", "to" => ["https://www.w3.org/ns/activitystreams#Public"], "type" => "Note", "updated" => "2025-08-04T01:53:18+02:00", "url" => "https://write.example.com/render-your-jupyter-notebooks-in-opengist"}, "published" => "2025-08-03T21:57:57+02:00", "type" => "Update", "updated" => "2025-08-04T01:53:18+02:00"} with: ** (KeyError) key :data not found in: nil
If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map
    (pleroma 3.15.2-makepkg) lib/pleroma/web/activity_pub/side_effects.ex:428: Pleroma.Web.ActivityPub.SideEffects.handle_update_object/2
    (pleroma 3.15.2-makepkg) lib/pleroma/web/activity_pub/pipeline.ex:50: Pleroma.Web.ActivityPub.Pipeline.do_common_pipeline/2
    (ecto_sql 3.12.1) lib/ecto/adapters/sql.ex:1400: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4
    (db_connection 2.7.0) lib/db_connection.ex:1756: DBConnection.run_transaction/4
    (pleroma 3.15.2-makepkg) lib/pleroma/web/activity_pub/pipeline.ex:28: Pleroma.Web.ActivityPub.Pipeline.common_pipeline/2
    (pleroma 3.15.2-makepkg) lib/pleroma/web/activity_pub/transmogrifier.ex:578: Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming_normalised/2
    (pleroma 3.15.2-makepkg) lib/pleroma/web/federator.ex:98: Pleroma.Web.Federator.perform/2
    (pleroma 3.15.2-makepkg) lib/pleroma/workers/receiver_worker.ex:14: Pleroma.Workers.ReceiverWorker.perform/1
```

Severity

I cannot use it as easily as I'd like

Have you searched for this issue?

  • I have double-checked and have not found this issue mentioned anywhere.
### Your setup OTP ### Extra details Arch Linux ### Version 3.15.2 ### PostgreSQL version 17.5 ### What were you trying to do? ### Summary When federating an ActivityPub `Update` activity from WriteFreely (and similar platforms), Akkoma/Pleroma crashes with the following error: ``` (KeyError) key :data not found in: nil lib/pleroma/web/activity_pub/side_effects.ex:428: Pleroma.Web.ActivityPub.SideEffects.handle_update_object/2 ... ``` ### Steps to Reproduce 1. Receive an ActivityPub `Update` activity from a remote server, where: - The activity has `"type": "Update"` - The `object` is a standard `Note` (or `Article`) with valid fields: `id`, `type`, `content`, `published`, `url`, etc. - Example payload: ```json { "@context": ["https://www.w3.org/ns/activitystreams"], "type": "Update", "id": "https://remote-server/api/posts/abcd1234", "actor": "https://remote-server/api/collections/user", "published": "2025-08-03T21:57:57+02:00", "updated": "2025-08-04T01:53:18+02:00", "object": { "type": "Note", "id": "https://remote-server/api/posts/abcd1234", "published": "2025-08-03T21:57:57+02:00", "updated": "2025-08-04T01:53:18+02:00", "url": "https://remote-server/render-your-jupyter-notebooks-in-opengist", "attributedTo": "https://remote-server/api/collections/user", "to": ["https://www.w3.org/ns/activitystreams#Public"], "cc": ["https://my-instance/users/me"], "name": "Title", "content": "<p>Some HTML post content</p>", "attachment": [ { "type": "Document", "url": "https://remote-server/img.png", "mediaType": "image/png" } ] } } ``` 2. Observe that the instance crashes and rejects the Update. ### Additional Notes - The same Update payload is accepted by Mastodon and other AP servers. - The crash appears to be a bug in the handling of Update activities for unknown objects. - The error log references `side_effects.ex` and the use of `.data` on a `nil` value. ### How to reproduce from scratch 1. Set up a remote AP server (WriteFreely, etc.). 2. Federate a post (Update activity) referencing an object ID not yet present on Akkoma. 3. Observe crash. ### Proposed Fix - Update should be handled gracefully if the object does not exist. - Do not crash the worker; return a 4xx error or log the rejection. ### What did you expect to happen? Akkoma/Pleroma should either: - Accept the Update if the referenced object exists. - Gracefully reject the Update if the object does not exist (with an error response), but **should not crash**. ### What actually happened? - The instance crashes with `(KeyError) key :data not found in: nil`. - This appears to happen if the Update refers to an object that was never created (never received a "Create" for that ID). ### Logs ````shell ``` 01:53:20.009 [error] Receiver worker CRASH on %{"@context" => ["https://www.w3.org/ns/activitystreams"], "actor" => "https://write.example.com/api/collections/fabio", "id" => "https://write.example.com/api/posts/d1e390ocd3", "object" => %{"attachment" => [%{"mediaType" => "image/png", "name" => "", "type" => "Document", "url" => "https://s3.example.com/fabio/img/gist-ipynb-screenshot-small.png"}, %{"mediaType" => "image/png", "name" => "", "type" => "Document", "url" => "https://s3.example.com/fabio/img/gist-ipynb-screenshot.png"}, %{"mediaType" => "image/png", "name" => "", "type" => "Document", "url" => "https://s3.example.com/fabio/img/gist-ipynb-screenshot-small.png"}, %{"mediaType" => "image/png", "name" => "", "type" => "Document", "url" => "https://s3.example.com/fabio/img/gist-ipynb-screenshot.png"}], "attributedTo" => "https://write.example.com/api/collections/fabio", "cc" => ["https://example.social/users/fabio"], "content" => "....", "id" => "https://write.example.com/api/posts/d1e390ocd3", "name" => "Render your Jupyter notebooks in OpenGist", "published" => "2025-08-03T21:57:57+02:00", "to" => ["https://www.w3.org/ns/activitystreams#Public"], "type" => "Note", "updated" => "2025-08-04T01:53:18+02:00", "url" => "https://write.example.com/render-your-jupyter-notebooks-in-opengist"}, "published" => "2025-08-03T21:57:57+02:00", "type" => "Update", "updated" => "2025-08-04T01:53:18+02:00"} with: ** (KeyError) key :data not found in: nil If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map (pleroma 3.15.2-makepkg) lib/pleroma/web/activity_pub/side_effects.ex:428: Pleroma.Web.ActivityPub.SideEffects.handle_update_object/2 (pleroma 3.15.2-makepkg) lib/pleroma/web/activity_pub/pipeline.ex:50: Pleroma.Web.ActivityPub.Pipeline.do_common_pipeline/2 (ecto_sql 3.12.1) lib/ecto/adapters/sql.ex:1400: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4 (db_connection 2.7.0) lib/db_connection.ex:1756: DBConnection.run_transaction/4 (pleroma 3.15.2-makepkg) lib/pleroma/web/activity_pub/pipeline.ex:28: Pleroma.Web.ActivityPub.Pipeline.common_pipeline/2 (pleroma 3.15.2-makepkg) lib/pleroma/web/activity_pub/transmogrifier.ex:578: Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming_normalised/2 (pleroma 3.15.2-makepkg) lib/pleroma/web/federator.ex:98: Pleroma.Web.Federator.perform/2 (pleroma 3.15.2-makepkg) lib/pleroma/workers/receiver_worker.ex:14: Pleroma.Workers.ReceiverWorker.perform/1 ``` ```` ### Severity I cannot use it as easily as I'd like ### Have you searched for this issue? - [x] I have double-checked and have not found this issue mentioned anywhere.
Owner

This appears to be a duplicate of #888 and while an odd fluke, usually does not affect federation. Only if it repeatedly fails exhausting all retries will the received object actually be (ungracefully) dropped. By default it’s 5 attempts spread out over about half an hour.

Updates for unknown objects are already handled gracefully; the processing getting far enough to be in side effects implies it was able to dereference the object before.

This appears to be a duplicate of #888 and while an odd fluke, usually does not affect federation. Only if it repeatedly fails exhausting all retries will the received object actually be (ungracefully) dropped. By default it’s 5 attempts spread out over about half an hour. Updates for unknown objects are _already_ handled gracefully; the processing getting far enough to be in side effects implies it was able to dereference the object before.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
AkkomaGang/akkoma#963
No description provided.