{"record":{"id":"3bb586b0a328818d","repo":"nexu-io/open-design","slug":"workspace-resource-authority-unavailable","errorCode":"WORKSPACE_RESOURCE_AUTHORITY_UNAVAILABLE","errorMessage":"team resource authority is temporarily unavailable","messagePattern":"team resource authority is temporarily unavailable","errorType":"exception","errorClass":"TeamResourceAuthorityUnavailableError","httpStatus":503,"severity":"warning","filePath":"apps/daemon/src/collab/team-resource-share.ts","lineNumber":306,"sourceCode":" * `requestTeamVisibility`/`collabSync.requestTeamUnshare` instead of this\n * helper because projects don't go through `TeamResourceShareService`).\n *\n * Returns whether an unshare actually ran, so a caller — and its tests — can\n * assert on the real state transition instead of a \"was unshare called\" mock.\n * Deliberately does NOT swallow a thrown `TeamResourceShareForbiddenError`:\n * the caller's delete must abort rather than proceed past a failed unshare.\n */\nexport async function unshareIfCurrentlyShared(\n  service: Pick<TeamResourceShareService, 'sharedResources' | 'unshare'>,\n  resourceId: string,\n  scope: TeamResourceRequestScope,\n): Promise<boolean> {\n  let resources: TeamResourceShareRecord[];\n  try {\n    resources = await service.sharedResources(scope, { authoritative: true });\n  } catch (error) {\n    if (error instanceof TeamResourceAuthorityUnavailableError) throw error;\n    throw new TeamResourceAuthorityUnavailableError(error);\n  }\n  if (!resources.some((resource) => resource.id === resourceId)) return false;\n  return service.unshare(resourceId, scope);\n}\n\ninterface SharedResourceListPayload {\n  resources?: Array<{\n    id?: unknown;\n    kind?: unknown;\n    deletedAt?: unknown;\n    metadata?: unknown;\n    ownerMemberId?: unknown;\n    publishedVersion?: unknown;\n  }>;\n}\n\nexport function parseSharedResourceIds(\n  stdout: string,","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/collab/team-resource-share.ts#L288-L324","documentation":"Thrown by unshareIfCurrentlyShared when an authoritative Team Hub read (sharedResources with authoritative:true) fails for any reason. The error is a 503 retryable signal: the hub that owns the list of team-shared resources cannot be reached, so the caller cannot safely decide whether a resource is shared. The function deliberately re-throws an existing TeamResourceAuthorityUnavailableError as-is, and wraps any other failure (network timeout, Vela CLI crash, JSON parse error) into a new one so all hub-down conditions surface uniformly.","triggerScenarios":"Calling unshareIfCurrentlyShared(service, resourceId, scope) when the underlying Vela CLI Resource Hub is unreachable. This happens when service.sharedResources(scope, { authoritative: true }) rejects — Vela login session expired, Resource Hub API returned 5xx, network partition, or the Vela binary returned malformed stdout. The catch block at line 304 converts every non-authority error into TeamResourceAuthorityUnavailableError.","commonSituations":"A user deletes a design system that was previously team-shared, but their Vela login token has expired. The daemon tries to unshare from the hub first, the hub read fails, and the delete route aborts with this 503 rather than silently deleting locally and leaving a dangling hub entry. Also seen during network blips, VPN drops, or when the Resource Hub backend is under maintenance.","solutions":["Retry the delete operation after confirming Vela login is active (od login status or re-authenticate via the Team Hub login flow).","Check network connectivity to the Resource Hub endpoint and verify the hub service is operational.","If using a cached/expired session, trigger a token refresh through the Vela CLI resolver before retrying the unshare.","If the hub is genuinely down, surface the 503 to the user and queue the operation for retry rather than proceeding with a local-only delete that would leave a dangling hub entry."],"exampleFix":"// before — swallowing the authority error and proceeding with delete\ntry {\n  await unshareIfCurrentlyShared(service, resourceId, scope);\n} catch {\n  // ignore and delete locally — WRONG: leaves dangling hub entry\n}\nawait deleteResource(resourceId);\n\n// after — propagate the 503 so the caller can retry or surface to user\ntry {\n  await unshareIfCurrentlyShared(service, resourceId, scope);\n} catch (error) {\n  if (error instanceof TeamResourceAuthorityUnavailableError) {\n    return res.status(503).json({\n      code: 'WORKSPACE_RESOURCE_AUTHORITY_UNAVAILABLE',\n      message: 'Team hub is temporarily unavailable. Please retry.',\n      retryable: true,\n    });\n  }\n  throw error;\n}\nawait deleteResource(resourceId);","handlingStrategy":"retry","validationCode":"// Before calling unshareIfCurrentlyShared, verify Vela login is active.\n// This is a best-effort pre-check; the hub may still fail at read time.\nasync function isAuthorityLikelyReachable(vela: VelaCliResolver): Promise<boolean> {\n  try {\n    const status = await vela.loginStatus();\n    return status === 'logged_in';\n  } catch {\n    return false;\n  }\n}\n\nif (!(await isAuthorityLikelyReachable(vela))) {\n  return res.status(503).json({\n    code: 'WORKSPACE_RESOURCE_AUTHORITY_UNAVAILABLE',\n    message: 'Team hub login is inactive. Please re-authenticate.',\n    retryable: true,\n  });\n}","typeGuard":"export function isTeamResourceAuthorityUnavailableError(\n  error: unknown,\n): error is TeamResourceAuthorityUnavailableError {\n  return error instanceof TeamResourceAuthorityUnavailableError;\n}\n\n// Usage:\nif (isTeamResourceAuthorityUnavailableError(error)) {\n  // error.status === 503, error.retryable === true\n  // safe to retry after backoff\n}","tryCatchPattern":"try {\n  const unshared = await unshareIfCurrentlyShared(service, resourceId, scope);\n  await deleteResource(resourceId);\n} catch (error) {\n  if (error instanceof TeamResourceAuthorityUnavailableError) {\n    // 503 retryable — surface to client with Retry-After header\n    res.set('Retry-After', '5');\n    return res.status(503).json({\n      code: error.code,\n      message: error.message,\n      retryable: error.retryable,\n    });\n  }\n  // Non-authority errors (e.g., TeamResourceShareForbiddenError) propagate\n  throw error;\n}","preventionTips":["Always check Vela login status before attempting team resource operations.","Never swallow TeamResourceAuthorityUnavailableError to proceed with a local-only delete — it leaves dangling hub entries.","Implement exponential backoff for 503 responses from the hub.","Monitor hub availability and queue operations during outages rather than failing the user action."],"tags":["network","collab","retryable","team-resources","vela"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}