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

  1. Always construct host ids with the shared helpers toSshExecutionHostId / toRuntimeExecutionHostId, never by string concatenation.
  2. Validate the host id with parseExecutionHostId on the renderer before invoking the IPC.
  3. If you hold a raw target id, wrap it: toSshExecutionHostId(targetId) before sending.
  4. 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

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


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/be986e0da63f6740. Report an issue: GitHub.