import { TextField } from "@opencode-ai/ui/text-field" import { Logo } from "@opencode-ai/ui/logo" import { Button } from "@opencode-ai/ui/button" import { Component } from "solid-js" import { usePlatform } from "@/context/platform" import { Icon } from "@opencode-ai/ui/icon" export type InitError = { name: string data: Record } function isInitError(error: unknown): error is InitError { return ( typeof error === "object" && error !== null && "name" in error && "data" in error && typeof (error as InitError).data === "object" ) } function formatInitError(error: InitError): string { const data = error.data switch (error.name) { case "MCPFailed": return `MCP server "${data.name}" failed. Note, opencode does not support MCP authentication yet.` case "ProviderModelNotFoundError": { const { providerID, modelID, suggestions } = data as { providerID: string modelID: string suggestions?: string[] } return [ `Model not found: ${providerID}/${modelID}`, ...(Array.isArray(suggestions) && suggestions.length ? ["Did you mean: " + suggestions.join(", ")] : []), `Check your config (opencode.json) provider/model names`, ].join("\n") } case "ProviderInitError": return `Failed to initialize provider "${data.providerID}". Check credentials and configuration.` case "ConfigJsonError": return `Config file at ${data.path} is not valid JSON(C)` + (data.message ? `: ${data.message}` : "") case "ConfigDirectoryTypoError": return `Directory "${data.dir}" in ${data.path} is not valid. Rename the directory to "${data.suggestion}" or remove it. This is a common typo.` case "ConfigFrontmatterError": return `Failed to parse frontmatter in ${data.path}:\n${data.message}` case "ConfigInvalidError": { const issues = Array.isArray(data.issues) ? data.issues.map( (issue: { message: string; path: string[] }) => "↳ " + issue.message + " " + issue.path.join("."), ) : [] return [`Config file at ${data.path} is invalid` + (data.message ? `: ${data.message}` : ""), ...issues].join( "\n", ) } case "UnknownError": return String(data.message) default: return data.message ? String(data.message) : JSON.stringify(data, null, 2) } } function formatErrorChain(error: unknown, depth = 0): string { if (!error) return "Unknown error" const indent = depth > 0 ? `\n${"─".repeat(40)}\nCaused by:\n` : "" if (isInitError(error)) { return indent + formatInitError(error) } if (error instanceof Error) { const parts = [indent + `${error.name}: ${error.message}`] if (error.stack) { parts.push(error.stack) } if (error.cause) { parts.push(formatErrorChain(error.cause, depth + 1)) } return parts.join("\n\n") } if (typeof error === "string") return indent + error return indent + JSON.stringify(error, null, 2) } function formatError(error: unknown): string { return formatErrorChain(error, 0) } interface ErrorPageProps { error: unknown } export const ErrorPage: Component = (props) => { const platform = usePlatform() return (

Something went wrong

An error occurred while loading the application.

Please report this error to the OpenCode team
) }