mihomo-party-org/clash-party · warning · Error

osascript exited ${res.status}

Error message

osascript exited ${res.status}

What it means

getLocalizedAppName shells out to macOS `osascript` (AppleScript via Sp.spawnSync-style exec) to ask the system for a localized app name. If the script process exits with a non-zero status and stderr is empty, this generic fallback 'osascript exited <status>' is thrown. It means the AppleScript run itself failed (syntax, sandboxing, or the target app not found), not a spawn failure (that would throw res.error instead).

Source

Thrown at src/main/utils/appName.ts:60

function getLocalizedAppName(appPath: string): string {
  const escapedPath = appPath.replace(/\\/g, '\\\\').replace(/'/g, "\\'")
  const jxa = `
  ObjC.import('Foundation');
  const fm = $.NSFileManager.defaultManager;
  const name = fm.displayNameAtPath('${escapedPath}');
  name.js;
`
  const res = spawnSync('osascript', ['-l', 'JavaScript'], {
    input: jxa,
    encoding: 'utf8',
    stdio: ['pipe', 'pipe', 'pipe']
  })
  if (res.error) {
    throw res.error
  }
  if (res.status !== 0) {
    throw new Error(res.stderr.trim() || `osascript exited ${res.status}`)
  }
  return res.stdout.trim()
}

View on GitHub (pinned to 911e090537)

Solutions

  1. Run the same osascript command manually in Terminal with the same app path to see the real failure and reproduce it.
  2. Grant Automation/AppleEvents permission for the app in System Settings > Privacy & Security > Automation (or add the AppleEvents entitlement).
  3. Validate the app path exists before querying and skip/short-circuit missing apps.
  4. Fall back to the raw bundle name from the .app directory instead of the localized name when osascript fails.
  5. Reinstall/relocate the target application if its bundle is broken or was moved.

Example fix

// before
const name = getLocalizedAppName('/Applications/OldName.app')
// after: guard existence and degrade gracefully
import { existsSync } from 'fs'
const path = '/Applications/OldName.app'
let name = basename(path, '.app')
if (existsSync(join(path, 'Contents', 'Info.plist'))) {
  try {
    name = getLocalizedAppName(path)
  } catch {
    /* keep bundle-name fallback */
  }
}
Defensive patterns

Strategy: fallback

Validate before calling

import { existsSync } from 'fs'
// check the app bundle exists before asking osascript about it
const appPath = '/Applications/SomeApp.app'
if (!existsSync(appPath)) {
  throw new Error(`App bundle missing: ${appPath}`)
}

Try / catch

let name: string
try {
  name = getLocalizedAppName(appPath)
} catch {
  // fall back to the bundle directory name
  name = basename(appPath, '.app')
}

Prevention

When it happens

Trigger: Calling appName -> getLocalizedAppName on macOS where osascript returns status != 0 with empty stderr — e.g. the AppleScript references an app path that no longer exists, or Automation/TCC permission denies the query and stderr is swallowed.

Common situations: App renamed/removed between listing and lookup; running in an environment where osascript is blocked (CI, hardened runtime without Apple Events entitlement); macOS update changes scripting interface; running as root without a GUI session.

Related errors


AI-assisted analysis of mihomo-party-org/clash-party@911e090537 (2026-08-30). Data as JSON: /api/errors/a0be6b725a756376. Report an issue: GitHub.