(null) is not allowed to open documents in Terminal

My application contains a binary which calls a shell script located in the "Resources" folder through the command: open -b com.apple.terminal '../Resources/myScript.sh' which opens the script in a Terminal window.

This works on a M1 computer and on Intel macOS prior to Ventura. On an Intel Mac upgraded to Ventura 13.2 I get the error message: "myscript.sh" can’t be opened because (null) is not allowed to open documents in Terminal.

Adding the entitlement <com.apple.security.automation.apple-events> had no effect.

Since this works on macOS other than Ventura for Intel I don't see which hardening key or whatsoever is missing.

What can I do to get rid of that error ?

All the best

Replies

Is your app sandboxed?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Notararized only. I got the impression that is not possible to sandbox an X11 based application or at least I failed to do so. As a workaround I will try to call the Terminal through an osacript.

All the best Alain

Ah, you mistake me. I was asking because sandboxing makes this harder.

Anyway, I believe you’re hitting a known bug in macOS 13 (FB11745075). The bug affects anyone who uses NSWorkspace, and that includes the open tool. I took a TSI about this last year and was able to work around the bug by sending an Apple event directly. I’ve pasted a snippet in below. However, given that you’re not calling NSWorkspace directly, your idea of using osacript is probably the easiest path forward for you.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@IBAction
private func testAppleEventAction(_ sender: Any) {
    self.status = "Opening with Apple event…"
    let url = FileManager.default.temporaryDirectory.appendingPathComponent("tmp.sh")
    let script = """
        #! /bin/sh
        echo 'Hail Teapot! (Apple event)'
        """
    do {
        try script.write(to: url, atomically: true, encoding: .utf8)
        let success = chmod(url.path, 0o755) >= 0
        guard success else { throw POSIXError(.init(rawValue: errno)!) }
    } catch let error as NSError {
        self.status = "Did not open, write error (\(error.domain) / \(error.code))"
        return
    }
    guard let terminal = NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.Terminal").first else {
        self.status = "Terminal is not open."
        return
    }
    
    // Create a 'aevt' / 'odoc' Apple event.
    
    let target = NSAppleEventDescriptor(processIdentifier: terminal.processIdentifier)
    let event = NSAppleEventDescriptor(
        eventClass: AEEventClass(kCoreEventClass),
        eventID: AEEventID(kAEOpenDocuments),
        targetDescriptor: target,
        returnID: AEReturnID(kAutoGenerateReturnID),
        transactionID: AETransactionID(kAnyTransactionID)
    )
    
    // Set its direct option to a list containing our script file URL.
    
    let scriptURL = NSAppleEventDescriptor(fileURL: url)
    let itemsToOpen = NSAppleEventDescriptor.list()
    itemsToOpen.insert(scriptURL, at: 0)
    event.setParam(itemsToOpen, forKeyword: keyDirectObject)
    
    // Send the Apple event.
    
    do {
        let reply = try event.sendEvent(options: [.waitForReply], timeout: 60.0)

        // AFAICT there’s no point looking at the reply here.  Terminal
        // doesn’t report errors this way.
        _ = reply
        
        // If the event was sent successfully, bring Terminal to the front.
        
        terminal.activate()
    } catch let error as NSError {
        self.status = "Did not open (\(error.domain) / \(error.code))"
        return
    }
    self.status = "Did open."
}

Thank you very much. As you said I cannot use your trick since I do not call NSWorkspace directly. Fortunately enough, a mere osascript solved the case.

I noticed that the behaviour of Terminal calls changed since a recent update of Big Sur etc. I wonder if this is a related problem. My X11 based app is organised as follows: [MacOS folder] mybinary --> [Resources] myScript.sh --> myToolBar --> binary_01, binary_02, [...], binary_xx If myScript.sh is called without opening a Terminal window, any of the binaries "binary_xx" when they call "xterm -e" no Terminal window is shown. If myScript.sh is called from an opened Terminal window, "binary_xx" can open a Terminal window too. It is quite strange that now any "binary_xx" inherits a hidden/visible Terminal window from the initial shell script call. As I said my first notice of the problem after a recent Big Sur upgrade but it also affects other macOS versions. This is just to inform you since this is not a blocking problem, at least for me. Just an unwanted extra Window ... I can live with it.

All the best