stablyai/orca · warning · Error

Preset name is required.

Error message

Preset name is required.

What it means

Thrown by normalizeSparsePresetName when, after trimming, the name is empty. This runs inside the sparsePresets:save handler after the repo existence check, before length and directory validation. The cap is 80 characters (see 1290).

Source

Thrown at src/main/ipc/repos.ts:2766

  try {
    repoRemoteClientNotifier?.notifyReposChangedForRemoteClients()
  } catch (err) {
    // Why: a broadcast failure must never fail the mutation the user actually asked for.
    console.error('[repos] failed to notify remote clients of repo change', err)
  }
  scheduleCurrentWorktreeBaseDirectoryWatcherSync()
}

function notifySparsePresetsChanged(mainWindow: BrowserWindow, repoId: string): void {
  if (!mainWindow.isDestroyed()) {
    mainWindow.webContents.send('sparsePresets:changed', { repoId })
  }
}

function normalizeSparsePresetName(name: string): string {
  const trimmed = name.trim()
  if (!trimmed) {
    throw new Error('Preset name is required.')
  }
  if (trimmed.length > 80) {
    throw new Error('Preset name is too long.')
  }
  return trimmed
}

function normalizeSparsePresetDirectories(directories: string[]): string[] {
  let normalized: string[]
  try {
    normalized = normalizeSparseDirectories(directories)
  } catch (err) {
    if (
      err instanceof Error &&
      err.message === 'Sparse checkout directories must be repo-relative paths.'
    ) {
      throw new Error('Preset directories must be repo-relative paths.')
    }

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Make the name input required and disable Save until a non-whitespace name is entered.
  2. Trim and validate in the renderer (name.trim().length > 0) before invoking save.
  3. Pre-fill a sensible default name (e.g. 'Preset ' + count) so empty submits are impossible.
  4. On catch, focus the name field and show an inline validation message.

Example fix

// before
ipc.invoke('sparsePresets:save', { repoId, name: nameInput, directories })

// after
const name = nameInput.trim()
if (!name) {
  setError('Name is required')
  return
}
ipc.invoke('sparsePresets:save', { repoId, name, directories })
Defensive patterns

Strategy: validation

Validate before calling

const name = rawName.trim()
if (!name) {
  setError('Preset name is required')
  return
}
await ipc.invoke('sparsePresets:save', { repoId, name, directories })

Type guard

function isNonEmptyName(value: unknown): value is string {
  return typeof value === 'string' && value.trim().length > 0
}

Try / catch

try {
  await ipc.invoke('sparsePresets:save', { repoId, name, directories })
} catch (e) {
  if (/name is required/i.test((e as Error).message)) focusNameField()
  else throw e
}

Prevention

When it happens

Trigger: Saving a preset with a blank name, a name of only whitespace, or a name field that was never populated by the form. The renderer did not enforce required-ness before the IPC call.

Common situations: Form submitted without validation; a default empty string placeholder leaked through; paste of whitespace-only content; programmatic save from a template missing the name field.

Related errors


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