stablyai/orca · warning · Error

A Claude config directory path is required.

Error message

A Claude config directory path is required.

What it means

Thrown by captureFromExistingConfigDir() when the provided configDir trims to an empty string. The method requires a real CLAUDE_CONFIG_DIR path to read credentials from; an empty/whitespace-only argument is rejected before any filesystem work.

Source

Thrown at src/main/claude-accounts/service.ts:211

        captured
      )
    } catch (error) {
      await this.cleanupFailedAdd(accountId, managedAuth.managedAuthPath, previousSettings, error)
      throw error
    }
  }

  // Why: capture credentials from a CLAUDE_CONFIG_DIR the caller already
  // authenticated (e.g. a temp dir the CLI ran `claude login` into), mirroring
  // runClaudeLoginAndCapture's capture step but without spawning the interactive
  // login. On Linux/Windows the credentials live in a plaintext `.credentials.json`.
  private async captureFromExistingConfigDir(
    configDir: string,
    previousLegacyCredentialsSha256?: string | null
  ): Promise<CapturedClaudeAuth> {
    const trimmed = configDir.trim()
    if (!trimmed) {
      throw new Error('A Claude config directory path is required.')
    }
    const resolvedDir = resolve(trimmed)
    // Why: macOS keeps Claude credentials in the Keychain rather than a file, so
    // only require `.credentials.json` off-darwin; captureAuthFromConfigDir reads
    // the scoped Keychain item on macOS.
    if (process.platform !== 'darwin' && !existsSync(join(resolvedDir, '.credentials.json'))) {
      throw new Error(
        `No Claude credentials found in ${resolvedDir}. Run \`claude login\` into this directory first.`
      )
    }
    // Why: `allowFailure` covers a non-zero exit but not a spawn error, and unlike
    // the GUI flow nothing has run `claude` in this process yet — a daemon started
    // with a minimal PATH (launchd/systemd) would hard-fail an add the user already
    // signed in for. Identity still resolves from the config dir's oauthAccount.
    let status = ''
    try {
      status = await this.runClaudeCommand(
        ['auth', 'status', '--json'],

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Validate configDir is a non-empty string at the caller (IPC handler) before invoking captureFromExistingConfigDir.
  2. Provide a clear UI validation error for an empty directory field.
  3. Default to a known CLAUDE_CONFIG_DIR if the user intends the default location.

Example fix

// before
const trimmed = configDir.trim()
if (!trimmed) {
  throw new Error('A Claude config directory path is required.')
}

// after — caller
if (!configDir?.trim()) {
  return { error: 'Config directory is required' }
}
Defensive patterns

Strategy: validation

Validate before calling

if (!configDir || !configDir.trim()) {
  throw new Error('Config directory path is required')
}

Prevention

When it happens

Trigger: Calling captureFromExistingConfigDir(''), captureFromExistingConfigDir(' '), or passing a path that becomes empty after .trim(). Typically an IPC handler or caller that forwarded an undefined/blank input.

Common situations: UI 'import from existing dir' form submitted empty. A programmatic caller passing undefined coerced to ''. A template/string concatenation bug producing an empty path.

Related errors


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