{"record":{"id":"c6a1eca7c23fa22a","repo":"RocketChat/Rocket.Chat","slug":"failed-to-build-external-url","errorCode":null,"errorMessage":"Failed to build external url","messagePattern":"Failed to build external url","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/client/apps/orchestrator.ts","lineNumber":144,"sourceCode":"\n\t\tif ('app' in result) {\n\t\t\treturn result.app;\n\t\t}\n\t\tthrow new Error('App not found');\n\t}\n\n\tpublic async buildExternalUrl(appId: string, purchaseType: 'buy' | 'subscription' = 'buy', details = false): Promise<IAppExternalURL> {\n\t\tconst result = await sdk.rest.get('/apps/buildExternalUrl', {\n\t\t\tappId,\n\t\t\tpurchaseType,\n\t\t\tdetails: `${details}`,\n\t\t});\n\n\t\tif ('url' in result) {\n\t\t\treturn result;\n\t\t}\n\n\t\tthrow new Error('Failed to build external url');\n\t}\n\n\tpublic async buildExternalAppRequest(appId: string) {\n\t\tconst result = await sdk.rest.get('/apps/buildExternalAppRequest', {\n\t\t\tappId,\n\t\t});\n\n\t\tif ('url' in result) {\n\t\t\treturn result;\n\t\t}\n\t\tthrow new Error('Failed to build App Request external url');\n\t}\n\n\tpublic async buildIncompatibleExternalUrl(appId: string, appVersion: string, action: string): Promise<IAppExternalURL> {\n\t\tconst result = await sdk.rest.get('/apps/incompatibleModal', {\n\t\t\tappId,\n\t\t\tappVersion,\n\t\t\taction,","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/client/apps/orchestrator.ts#L126-L162","documentation":"Thrown by AppClientOrchestrator.buildExternalUrl when GET /apps/buildExternalUrl returns a body without a `url` key. This endpoint builds a purchase/subscription redirect URL (marketplace checkout); if the server does not return the expected { url } field, the method cannot produce a valid redirect target and throws.","triggerScenarios":"Calling buildExternalUrl(appId, purchaseType, details) where the marketplace integration is misconfigured, the appId has no purchase flow, the server returns an error envelope with HTTP 200, or the buildExternalUrl route is unavailable in the deployed server version.","commonSituations":"Marketplace not configured (no 3CX/Marketplace registration); the app is free/no-op so no external URL is built; entitlement/billing service down; server version predates the buildExternalUrl endpoint; proxy returning an error page with 200.","solutions":["Check the raw GET /apps/buildExternalUrl response body for the actual server reply.","Ensure the marketplace is registered and the appId is a paid app that requires an external URL.","Verify the server version supports the buildExternalUrl route.","If the entitlement service is down, retry later or fall back to the in-app purchase flow."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function hasUrlKey(r: unknown): r is { url: string } {\n  return typeof r === 'object' && r !== null && 'url' in r;\n}","tryCatchPattern":"try {\n  const { url } = await orchestrator.buildExternalUrl(appId, purchaseType);\n} catch (e) {\n  if ((e as Error).message === 'Failed to build external url') {\n    showMarketplaceConfigWarning();\n  }\n}","preventionTips":["Ensure the marketplace is registered before offering purchase flows.","Confirm the server version supports the buildExternalUrl route.","Retry when the entitlement/billing service may be transiently down."],"tags":["apps-engine","marketplace","rest","response-shape","purchase"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}