{"record":{"id":"6fa2ba500d6e3581","repo":"different-ai/openwork","slug":"failed-to-preview-github-plugin-components","errorCode":null,"errorMessage":"Failed to preview GitHub plugin components.","messagePattern":"Failed to preview GitHub plugin components\\.","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/plugin-import-screen.tsx","lineNumber":78,"sourceCode":"    try {\n      normalizedGithubUrl = normalizePublicGitHubPluginUrl(githubUrl);\n    } catch (urlError) {\n      setError(urlError instanceof Error ? urlError.message : \"Enter a valid public GitHub plugin URL.\");\n      return;\n    }\n\n    setBusy(true);\n    setError(null);\n    try {\n      let payload: unknown = null;\n      await runReauthableAction(\"preview-github-plugin-components\", async () => {\n        const result = await requestJson(\n          \"/v1/plugins/import-mcps-from-github-url/preview\",\n          { method: \"POST\", body: JSON.stringify({ githubUrl: normalizedGithubUrl }) },\n          20000,\n        );\n        if (!result.response.ok) {\n          throw getRequestError(result.payload, result.response, \"Failed to preview GitHub plugin components.\");\n        }\n        payload = result.payload;\n      });\n      const nextPreview = parsePluginImportPreview(payload);\n      setGithubUrl(normalizedGithubUrl);\n      setPreview(nextPreview);\n      setSelectedServerKeys(nextPreview.servers.filter((server) => server.supported).map((server) => server.serverKey));\n      setSelectedSkillKeys(nextPreview.skills.filter((skill) => skill.supported).map((skill) => skill.skillKey));\n    } catch (previewError) {\n      setError(previewError instanceof Error ? previewError.message : \"Failed to preview GitHub plugin components.\");\n    } finally {\n      setBusy(false);\n    }\n  }\n\n  function continueToCreate() {\n    if (!preview || (selectedServerKeys.length === 0 && selectedSkillKeys.length === 0)) {\n      setError(\"Select at least one supported MCP server or skill.\");","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/plugin-import-screen.tsx#L60-L96","documentation":"previewImport in plugin-import-screen.tsx throws this when POSTing a githubUrl to /v1/plugins/import-mcps-from-github-url/preview returns non-ok. The endpoint asks the Den server to fetch and parse the GitHub repo into importable components; the error means the server-side fetch/parse failed. Payload from getRequestError holds the server's reason.","triggerScenarios":"POST with a normalized GitHub URL returns 4xx/5xx: malformed or non-GitHub URL (400), repo not found or private (404/403), GitHub rate limit on the server side (429/502), or repo too large to analyze (timeout within 20s).","commonSituations":"Pasting a private repo URL expecting import to work; pasting a gitlab/bitbucket URL; org's Den server IP rate-limited by GitHub during bulk imports; repo with no recognizable MCP components.","solutions":["Verify the URL is a public GitHub repository URL (https://github.com/owner/repo...) and correct typos.","If the repo is private, make it public or use the org's configured GitHub connection with access.","Check the server payload: 429/502 indicates GitHub rate limiting — wait and retry.","Confirm the repo actually contains MCP/plugin components the importer recognizes."],"exampleFix":"// before\nawait previewImport(userInput);\n// after: cheap client-side sanity check first\nif (!/^https:\\/\\/github\\.com\\/[\\w.-]+\\/[\\w.-]+/.test(userInput)) {\n  throw new Error('Enter a public GitHub repository URL.');\n}\nawait previewImport(userInput);","handlingStrategy":"validation","validationCode":"const GITHUB_URL = /^https:\\/\\/github\\.com\\/[\\w.-]+\\/[\\w.-]+/;\nif (!GITHUB_URL.test(input.trim())) {\n  setError('Enter a GitHub repository URL, e.g. https://github.com/owner/repo');\n  return;\n}","typeGuard":"function isGitHubRepoUrl(v: unknown): v is string {\n  return typeof v === 'string' && /^https:\\/\\/github\\.com\\/[\\w.-]+\\/[\\w.-]+/.test(v);\n}","tryCatchPattern":"try {\n  const next = await previewImport(url);\n  setPreview(next);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  toast(/429|502/.test(msg)\n    ? 'GitHub is rate-limiting the import. Try again in a few minutes.'\n    : /404|403/.test(msg)\n      ? 'Repository not found or private. Use a public repo.'\n      : msg);\n}","preventionTips":["Validate the URL shape client-side before calling the preview endpoint.","Document that only public GitHub repos are importable (or configure a GitHub connection).","Rate-limit repeated preview submissions to avoid server-side GitHub 429s.","Keep the 20s timeout in mind for very large repos; warn users about size."],"tags":["http","api","github","plugin-import"],"backgroundTag":"github-repo-unreachable","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}