Index: src/services/ActivityPubService.js
===================================================================
--- src/services/ActivityPubService.js	(revision cae7bfc26a1a28c757ad9371ff6fce0dbc1530e5)
+++ src/services/ActivityPubService.js	(revision c49808e7517a5948f14dfd43ec1c3fdadd73e464)
@@ -1312,8 +1312,16 @@
   const icon = doc && doc.icon ? (doc.icon.url || (Array.isArray(doc.icon) && doc.icon[0] && doc.icon[0].url)) : null;
   const name = (doc && (doc.name || doc.preferredUsername)) || handle;
+  // Een AS2 `url` mag een ARRAY van Links zijn -- onze eigen buildActor doet
+  // dat (profiel + RSS), en een oudere consument stringde die array tot
+  // "[object Object],[object Object]" in de mention-hrefs van een hulpvraag
+  // (Barts vondst, 8-8). pickLink kiest de html-Link; de kale string blijft
+  // de gewone weg, en de actor-id de terugval.
+  const profiel = (doc && Array.isArray(doc.url))
+    ? ((pickLink(doc.url, (mt) => !mt || /html/i.test(mt)) || {}).href || safeUrl(doc.id || actorUri))
+    : safeUrl((doc && (doc.url || doc.id)) || actorUri);
   return {
     name,
     handle,
-    url: safeUrl((doc && (doc.url || doc.id)) || actorUri) || null,
+    url: profiel || null,
     icon: safeUrl(icon) || null,
     // FEP-9098 custom emojis in the display name (":shortcode:"), so the byline
Index: test/own-card.test.js
===================================================================
--- test/own-card.test.js	(revision cae7bfc26a1a28c757ad9371ff6fce0dbc1530e5)
+++ test/own-card.test.js	(revision c49808e7517a5948f14dfd43ec1c3fdadd73e464)
@@ -88,2 +88,38 @@
   assert.deepEqual(await AP.previewCard('geen url'), {});
 });
+
+
+test('actorInfo kiest de html-Link uit een url-array (geen object-stringing)', async () => {
+  // Barts vondst (8-8): buildActor serveert `url` als array van Links
+  // (profiel + RSS), en een consument die dat niet kent stringde de array tot
+  // "[object Object],[object Object]" in de mention-href van een HULPVRAAG.
+  // De thread-byline loopt door dezelfde actorInfo, dus die legt het vast.
+  const HOST = 'https://203.0.113.62';
+  const NOTE = `${HOST}/notes/n1`;
+  const AUTEUR = `${HOST}/users/array`;
+  const vorige = globalThis.fetch;
+  globalThis.fetch = async (url) => {
+    const u = String(url);
+    const json = (o) => new Response(JSON.stringify(o), { status: 200, headers: { 'content-type': 'application/activity+json' } });
+    if (u === NOTE) return json({
+      id: NOTE, type: 'Note', attributedTo: AUTEUR, content: '<p>bron</p>',
+      replies: { type: 'Collection', first: { type: 'CollectionPage', items: [
+        { id: `${NOTE}/r1`, type: 'Note', attributedTo: AUTEUR, inReplyTo: NOTE, content: '<p>antwoord</p>', published: '2026-08-02T10:00:00Z' },
+      ] } },
+    });
+    if (u === AUTEUR) return json({
+      id: AUTEUR, type: 'Person', preferredUsername: 'array', inbox: `${AUTEUR}/inbox`,
+      url: [
+        { type: 'Link', href: `${HOST}/`, mediaType: 'text/html' },
+        { type: 'Link', href: `${HOST}/feed.xml`, mediaType: 'application/rss+xml' },
+      ],
+    });
+    return vorige(url);
+  };
+  const uit = await AP.getThread('schrijver', NOTE);
+  globalThis.fetch = vorige;
+  assert.equal(uit.notes.length, 1);
+  const auteur = uit.notes[0]['shaer:author'];
+  assert.equal(auteur.url, `${HOST}/`, 'de html-Link, niet de array gestringd');
+  assert.ok(!String(auteur.url).includes('object'), 'nergens [object Object]');
+});
