{"record":{"id":"085c5570518ffbe1","repo":"can1357/oh-my-pi","slug":"share-upload-to-base-failed-err-instanceof-e","errorCode":null,"errorMessage":"Share upload to ${base} failed: ${err instanceof Error ? err.message : String(err)}","messagePattern":"Share upload to (.+?) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/export/share.ts","lineNumber":675,"sourceCode":"\treturn {\n\t\turl: `${base}/${id}#${keyText}`,\n\t\tmethod: \"server\",\n\t\ttruncated: forServer.truncated,\n\t\tsealedBytes: forServer.sealed.byteLength,\n\t};\n}\n\n/** POST the sealed blob to the share server; returns the assigned id. */\nasync function uploadToServer(sealed: Uint8Array, base: string): Promise<string> {\n\tlet res: Response;\n\ttry {\n\t\tres = await fetch(base, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/octet-stream\" },\n\t\t\tbody: sealed,\n\t\t});\n\t} catch (err) {\n\t\tthrow new Error(`Share upload to ${base} failed: ${err instanceof Error ? err.message : String(err)}`);\n\t}\n\tif (!res.ok) {\n\t\tconst detail = (await res.text().catch(() => \"\")).trim().slice(0, 200);\n\t\tthrow new Error(`Share upload to ${base} failed: HTTP ${res.status}${detail ? ` (${detail})` : \"\"}`);\n\t}\n\tconst body = (await res.json().catch(() => null)) as { id?: unknown } | null;\n\tconst id = body && typeof body.id === \"string\" ? body.id : \"\";\n\tif (!/^[A-Za-z0-9_-]{10,64}$/.test(id)) {\n\t\tthrow new Error(`Share upload to ${base} failed: server returned no usable id`);\n\t}\n\treturn id;\n}\n","sourceCodeStart":657,"sourceCodeEnd":688,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/export/share.ts#L657-L688","documentation":"uploadToServer POSTs the sealed session blob to the share server as application/octet-stream. If the fetch itself throws — DNS failure, connection refused, TLS error, network timeout, request aborted — the raw low-level error is wrapped in this error naming the server base URL, so the caller gets one clear message instead of a bare TypeError.","triggerScenarios":"Calling share.forServer/uploadToServer when the share server base URL is unreachable: wrong hostname, server down, offline, blocked by proxy/firewall, or a malformed URL that fetch rejects before a response is received.","commonSituations":"No internet/VPN connection; self-hosted share server configured with a typo'd or stale URL (SHARE_SERVER env/config); corporate proxy blocking the POST; server temporarily down for maintenance; IPv6/DNS misconfiguration.","solutions":["Check network connectivity and that the share server host resolves and is reachable (curl -v POST to the base URL).","Verify the configured share server URL (env/config) — fix typos, protocol (https vs http), and trailing path.","Retry after transient failures; if a proxy/firewall is in the path, allowlist the share host.","If self-hosting, confirm the share server process is running and its port is exposed.","If the underlying err.message says 'fetch failed', inspect cause (e.g. ENOTFOUND, ECONNREFUSED) to pinpoint DNS vs connection issues."],"exampleFix":"// before\nconst url = await share.forServerUrl('https://share.internal.example/share'); // ECONNREFUSED\n// after\n// fix config / verify reachability first:\nconst base = process.env.OMP_SHARE_URL ?? 'https://share.oh-my-pi.dev';\nconst url = await share.forServerUrl(base);","handlingStrategy":"retry","validationCode":"// Cheap reachability probe before upload\nconst base = normalizeShareServerUrl(serverUrl);\nconst probe = await fetch(base, { method: 'HEAD' }).catch(() => null);\nif (!probe) throw new Error(`Share server ${base} unreachable`);","typeGuard":null,"tryCatchPattern":"try {\n  const id = await uploadToServer(base, sealed);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Share upload to')) {\n    // inspect err.message for the low-level cause; retry with backoff or fall back to gist\n  } else throw err;\n}","preventionTips":["Validate the share server URL config at startup","Retry transient network failures with exponential backoff","Provide a fallback path (e.g. gist or local export) when the server is unreachable","Monitor proxy/firewall rules for the share host in corporate environments"],"tags":["network","http","upload","sharing"],"backgroundTag":"network-request-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}