{"record":{"id":"8fb8055856bc31c7","repo":"ruvnet/ruflo","slug":"failed-to-create-share-link","errorCode":null,"errorMessage":"Failed to create share link","messagePattern":"Failed to create share link","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ruflo/src/ruvocal/src/lib/createShareLink.ts","lineNumber":22,"sourceCode":"// Returns a public share URL for a conversation id.\n// If `id` is already a 7-char share id, no network call is made.\nexport async function createShareLink(id: string): Promise<string> {\n\tconst prefix =\n\t\tpage.data.publicConfig.PUBLIC_SHARE_PREFIX ||\n\t\t`${page.data.publicConfig.PUBLIC_ORIGIN || page.url.origin}${base}`;\n\n\tif (id.length === 7) {\n\t\treturn `${prefix}/r/${id}`;\n\t}\n\n\tconst res = await fetch(`${base}/conversation/${id}/share`, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text().catch(() => \"\");\n\t\tthrow new Error(text || \"Failed to create share link\");\n\t}\n\n\tconst { shareId } = await res.json();\n\treturn `${prefix}/r/${shareId}`;\n}\n","sourceCodeStart":4,"sourceCodeEnd":28,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/ruflo/src/ruvocal/src/lib/createShareLink.ts#L4-L28","documentation":"Thrown by createShareLink after POST {base}/conversation/{id}/share returns a non-2xx response. The error prefers the response body text (if any) and falls back to the generic 'Failed to create share link'. It is a network/backend failure signal from the share endpoint, not a client-side validation error.","triggerScenarios":"The share POST responds with 4xx/5xx: conversation id not found (404), user not authorized (401/403), backend down (500/502), or rate limited (429). The id.length === 7 short-circuit path above (which builds a local /r/{id} URL) is skipped, so only the longer ids reach the network call.","commonSituations":"Sharing a conversation that was deleted or never persisted; calling createShareLink without a valid auth token/cookie; the share route handler threw; dev environment without a running backend so the POST 502s; CORS or network error making res.ok false.","solutions":["Inspect the actual response status/body — the thrown message often contains the backend's error text; log res.status before throwing if you control the call site.","Confirm the conversation id exists and belongs to the current user before sharing.","Ensure the request carries the auth token/cookie the share route requires.","Verify the backend share endpoint is up and reachable (check {base} and network)."],"exampleFix":"// before\nconst link = await createShareLink(id); // opaque failure\n\n// after\ntry {\n  const link = await createShareLink(id);\n} catch (e) {\n  console.error('share failed for', id, e.message);\n  // surface backend text, retry once, or degrade gracefully\n}","handlingStrategy":"try-catch","validationCode":"if (!id || typeof id !== 'string') throw new Error('conversation id required');\n// optionally HEAD the conversation to confirm it exists & belongs to the user before sharing","typeGuard":"function isValidConversationId(id: string): boolean { return typeof id === 'string' && id.length > 0; }","tryCatchPattern":"try { return await createShareLink(id); } catch (e) { console.error('share failed', id, (e as Error).message); return null; }","preventionTips":["Confirm the conversation exists and belongs to the user before sharing.","Ensure the auth token/cookie is on the request.","Log res.status at the call site to disambiguate backend failures."],"tags":["network","sharing","fetch","ruvocal"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}