stablyai/orca · error · Error
Unsupported host: ${args.hostId}
Error message
Unsupported host: ${args.hostId} What it means
Thrown by the projectHostSetups:setupExistingFolder IPC handler when parseExecutionHostId(args.hostId) returns null. parseExecutionHostId accepts exactly three forms: the literal local id, 'ssh:<encodeURIComponent(targetId)>', or 'runtime:<encodeURIComponent(environmentId)>'. Any other string (including a bare SSH target id, an empty runtime: prefix, or malformed URI encoding) yields null.
Source
Thrown at src/main/ipc/repos.ts:1433
notifyReposChanged(mainWindow)
return result
}
)
ipcMain.handle(
'projectHostSetups:setupExistingFolder',
async (
_event,
rawArgs: ProjectHostSetupExistingFolderArgs
): Promise<ProjectHostSetupResult> => {
const args = parseProjectGroupIpcArgs(
ProjectHostSetupExistingFolderIpcArgs,
rawArgs,
'project_host_setup_invalid_args'
)
const parsedHost = parseExecutionHostId(args.hostId)
if (!parsedHost) {
throw new Error(`Unsupported host: ${args.hostId}`)
}
const result =
parsedHost.kind === 'local'
? await addLocalRepoFromPath(store, args.path, args.kind)
: parsedHost.kind === 'ssh'
? await addRemoteRepoFromPath(store, {
connectionId: parsedHost.targetId,
remotePath: args.path,
displayName: args.displayName,
kind: args.kind
})
: {
error:
'Runtime hosts must be set up through the runtime projectHostSetup.setupExistingFolder RPC.'
}
if ('error' in result) {
throw new Error(result.error)
}View on GitHub (pinned to 1136503c6a)
Solutions
- Always construct host ids with the shared helpers toSshExecutionHostId / toRuntimeExecutionHostId, never by string concatenation.
- Validate the host id with parseExecutionHostId on the renderer before invoking the IPC.
- If you hold a raw target id, wrap it: toSshExecutionHostId(targetId) before sending.
- Ensure the encoded segment is non-empty and produced by encodeURIComponent.
Example fix
// before
ipc.invoke('projectHostSetups:setupExistingFolder', { hostId: sshTargetId, path })
// after
import { toSshExecutionHostId } from '@shared/execution-host'
ipc.invoke('projectHostSetups:setupExistingFolder', {
hostId: toSshExecutionHostId(sshTargetId),
path,
}) Defensive patterns
Strategy: type-guard
Validate before calling
import { parseExecutionHostId, toSshExecutionHostId, toRuntimeExecutionHostId } from '@shared/execution-host'
function buildHostId(host: { kind: 'local' } | { kind: 'ssh'; targetId: string } | { kind: 'runtime'; environmentId: string }): string {
if (host.kind === 'local') return 'local' // LOCAL_EXECUTION_HOST_ID
if (host.kind === 'ssh') return toSshExecutionHostId(host.targetId)
return toRuntimeExecutionHostId(host.environmentId)
}
const hostId = buildHostId(host)
if (!parseExecutionHostId(hostId)) throw new Error('Refusing to call IPC with unparseable host id')
ipc.invoke('projectHostSetups:setupExistingFolder', { hostId, path }) Type guard
import { parseExecutionHostId, type ParsedExecutionHost } from '@shared/execution-host'
function isValidHostId(value: unknown): value is string {
return typeof value === 'string' && parseExecutionHostId(value) !== null
} Try / catch
try {
await ipc.invoke('projectHostSetups:setupExistingFolder', { hostId, path })
} catch (e) {
if (/Unsupported host/.test((e as Error).message)) {
showError('This host type is not supported for folder setup.')
} else throw e
} Prevention
- Never build host ids by concatenation; use toSshExecutionHostId / toRuntimeExecutionHostId.
- Validate with parseExecutionHostId on the renderer before any host-scoped IPC.
- Keep host context bound to the row that originated the action.
When it happens
Trigger: Passing a raw SSH connection id without the 'ssh:' prefix and encodeURIComponent; passing 'runtime:' with an empty encoded segment; passing a display label or alias instead of the canonical host id; URI-encoding errors that make decodeURIComponent throw.
Common situations: Renderer builds the host id manually and forgets the prefix or the encoding; a host id is round-tripped through a component that double-decodes it; switching from the old bare-target id scheme to the prefixed scheme without migration.
Related errors
- Invalid host ID: ${args.hostId}
- Repo path must be an absolute path
- Preset name is required.
- Preset name is too long.
- Preset directories must be repo-relative paths.
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/be986e0da63f6740.
Report an issue: GitHub.