OpenHands/OpenHands · error · Error
Reading plugin files is only available on a local backend.
Error message
Reading plugin files is only available on a local backend.
What it means
Thrown by PluginsService.getPluginFileContent() when the active backend is cloud. This method reads a single plugin file's content from the agent-server's local disk via FileClient.downloadFile(). Plugin files (source code, skills, config) only exist on the local agent-server's filesystem, so reading them is meaningless and would fail against a cloud backend. The guard surfaces this as a clear error rather than a confusing 404/network error from the cloud endpoint.
Source
Thrown at src/api/plugins-service.ts:132
} catch {
return [];
}
}
/**
* Fetch one plugin file's content for the detail-modal viewer. `basePath` is
* the plugin directory reported by the agent-server (`path`/`install_path`)
* and `relativePath` a POSIX path from the plugin's `files` listing.
*
* Local backend only — plugin files live on the local agent-server's disk.
* Errors propagate so the caller can render a load-error state.
*/
static async getPluginFileContent(
basePath: string,
relativePath: string,
): Promise<PluginFileContent> {
if (getActiveBackend().backend.kind === "cloud") {
throw new Error(
"Reading plugin files is only available on a local backend.",
);
}
const buffer = await new FileClient(
getAgentServerClientOptions(),
).downloadFile(`${basePath}/${relativePath}`);
if (isLikelyBinary(buffer)) {
return { kind: "binary", text: null };
}
return {
kind: "text",
text: new TextDecoder("utf-8", { fatal: false }).decode(buffer),
};
}
}
export default PluginsService;View on GitHub (pinned to 500b4c533e)
Solutions
- Switch to a local backend to view plugin file contents.
- Gate the plugin file viewer / detail modal on backend.kind === 'local' and show a placeholder message for cloud.
- If viewing plugin source is needed in cloud, link to the plugin's upstream git repository instead of reading local files.
Example fix
// Gate the file viewer on local backend
const { backend } = getActiveBackend();
if (backend.kind !== 'local') {
return <Placeholder>File viewing requires a local backend.</Placeholder>;
}
<FileViewer path={path} /> Defensive patterns
Strategy: validation
Validate before calling
// Guard before calling getPluginFileContent
import { getActiveBackend } from '#/api/backend-registry/active-store';
if (getActiveBackend().backend.kind !== 'local') {
// Show a placeholder instead of fetching file content
return { kind: 'text', text: 'File viewing requires a local backend.' };
} Type guard
function isLocalActiveBackend(): boolean {
return getActiveBackend().backend.kind === 'local';
} Try / catch
try {
const content = await PluginsService.getPluginFileContent(basePath, relativePath);
} catch (error) {
if (error instanceof Error && error.message.includes('only available on a local backend')) {
setFileViewMode('unsupported');
} else {
throw error;
}
} Prevention
- Gate the plugin detail modal's file viewer on backend.kind === 'local'.
- Link to the plugin's upstream git repo for cloud users who want to browse files.
- Keep the file viewer component lazy-loaded so it does not mount unnecessarily on cloud.
When it happens
Trigger: Any call to PluginsService.getPluginFileContent(basePath, relativePath) when getActiveBackend().backend.kind === 'cloud'. Typically triggered when the plugin detail modal tries to render the file viewer while the user is on a cloud backend.
Common situations: The user opens a plugin's detail modal (which lists files and shows content) while connected to a Cloud backend, or the plugin file viewer component loads without checking the active backend kind.
Related errors
- Installing plugins is only available on a local backend.
- Enabling and disabling plugins is only available on a local
- Uninstalling plugins is only available on a local backend.
- Refreshing plugins is only available on a local backend.
- OAuth authorization requires a reachable local backend.
AI-assisted analysis of OpenHands/OpenHands@500b4c533e (2026-08-12).
Data as JSON: /api/errors/a31f92c53a67c3f4.
Report an issue: GitHub.