{"record":{"id":"3de512c9f4433841","repo":"LemmyNet/lemmy","slug":"err-getting-actor-actor-type-actor-apub-id","errorCode":null,"errorMessage":"err getting actor {actor_type:?} {actor_apub_id}: {e:?}","messagePattern":"err getting actor (.+?) (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/apub/send/src/util.rs","lineNumber":174,"sourceCode":"            .into(),\n        )),\n        ActorType::Person => Right(Left(\n          Person::read_from_apub_id(pool, &url)\n            .await?\n            .context(\"apub person not found\")?\n            .into(),\n        )),\n        ActorType::MultiCommunity => Left(Right(\n          MultiCommunity::read_from_apub_id(pool, &url)\n            .await?\n            .context(\"apub multi-comm not found\")?\n            .into(),\n        )),\n      };\n      Result::<_, LemmyError>::Ok(Arc::new(actor))\n    })\n    .await\n    .map_err(|e| anyhow::anyhow!(\"err getting actor {actor_type:?} {actor_apub_id}: {e:?}\"))\n}\n\ntype CachedActivityInfo = Option<Arc<SentActivity>>;\n/// activities are immutable so cache does not need to have TTL\n/// May return None if the corresponding id does not exist or is a received activity.\n/// Holes in serials are expected behaviour in postgresql\n/// todo: cache size should probably be configurable / dependent on desired memory usage\npub(crate) async fn get_activity_cached(\n  pool: &mut DbPool<'_>,\n  activity_id: ActivityId,\n) -> Result<CachedActivityInfo> {\n  static ACTIVITIES: LazyLock<Cache<ActivityId, CachedActivityInfo>> =\n    LazyLock::new(|| Cache::builder().max_capacity(10000).build());\n  ACTIVITIES\n    .try_get_with(activity_id, async {\n      Ok(Some(Arc::new(SentActivity::read(pool, activity_id).await?)))\n    })\n    .await","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/LemmyNet/lemmy/blob/439734dd638a2c06a2f907beab7dcf4646e88f86/crates/apub/send/src/util.rs#L156-L192","documentation":"get_actor_cached wraps any failure while loading an actor (person/community/etc.) from the DB by its ActivityPub ID into this anyhow error. It uses the underlying LemmyError as context, so the root cause is in the debug-printed inner error. send_retry_loop calls it before serializing the activity.","triggerScenarios":"Federation send for an activity whose actor_type + actor_apub_id does not resolve to a live actor row: deleted/removed actor, actor purged from DB, wrong actor_type, or an underlying DB query failure.","commonSituations":"Trying to federate an activity authored by a user or community that has since been deleted or removed by moderators; DB connectivity issues on the instance; stale cache entries pointing at removed actors.","solutions":["Check the inner debug error to see whether it is not-found vs a DB failure","Verify the actor still exists and is not marked deleted/removed in the database","Confirm activity.actor_type matches the actual actor kind at actor_apub_id","If DB-related, check database connectivity/health and retry the federation"],"exampleFix":"// before\nlet actor = get_actor_cached(pool, activity.actor_type, &actor_apub_id).await?; // fails for removed actor\n// after\nlet actor = match get_actor_cached(pool, activity.actor_type, &actor_apub_id).await {\n  Ok(a) => a,\n  Err(e) => { warn!(\"actor gone, dropping activity: {e:?}\"); continue; } // skip rather than retry forever\n};","handlingStrategy":"try-catch","validationCode":"// before sending, check the actor row exists\n// SELECT 1 FROM actor WHERE ap_id = $1 AND deleted = false AND removed = false","typeGuard":null,"tryCatchPattern":"match get_actor_cached(pool, activity.actor_type, &ap_id).await {\n  Ok(actor) => send_with(actor),\n  Err(e) => warn!(\"actor unavailable, dropping activity: {e:?}\"),\n}","preventionTips":["Skip (don't infinite-retry) activities whose actor was deleted/removed","Keep actor_type and ap_id consistent when constructing activities","Monitor DB health; actor lookups are DB-bound"],"tags":["activitypub","federation","database","actor-lookup"],"backgroundTag":"entity-not-found","analyzedSha":"439734dd638a2c06a2f907beab7dcf4646e88f86","analyzedAt":"2026-09-06T11:28:35.035Z","contentChangedAt":"2026-09-06T11:28:35.035Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}