Skip to content

OCR extremely slow / returns no text on macOS 27 Golden Gate (Vision VNRecognizeTextRequest regression) #439

Description

@Jason-K

Summary

Since upgrading to macOS 27 Golden Gate, macshot's OCR has become extremely slow and unreliable. The cause is an OS-side regression in Apple's Vision framework: the legacy VNRecognizeTextRequest at its default revision (revision 3) with .accurate recognition. The API behaves differently on 27, so the app needs a workaround.

Environment

  • macOS 27.0 Golden Gate
  • Apple Silicon (M4 Pro, 24 GB)

Behavior

  • The first .accurate request in each process stalls for about 15–30 seconds while the system compiles the model through the Neural Engine (E5RT).
  • Later requests in the same process return zero results with no error, or on some machines throw E5RT ... Code: 13, until the process restarts.

Reproduction (outside macshot)

A standalone PyObjC test ran sequential requests in one process against the same screenshot:

Request Time Result
.accurate, default revision, #1 26.9 s 0 text blocks
.accurate, default revision, #2–3 0.13 s 0 text blocks
.accurate, VNRecognizeTextRequestRevision2 0.12 s 3 text blocks ✅
.fast, default revision 0.07 s 6 text blocks ✅

Proposed fix

TRex hit the same problem and fixed it in amebalabs/TRex#95. The same regression is also reported in m-tkg/clipkun and jfarcand/mirroir-mcp#36.

  1. On macOS 15+, use the modern Swift Vision API (RecognizeTextRequest). It isn't affected and keeps full language support. Leave the existing path in place for macOS 12.3–14.
  2. Wrap each OCR attempt in a timeout of about 10 s. On timeout, error, or an empty result, retry once at .fast so a stalled model compile can't hang the OCR window.
  3. Fallback if the legacy API must stay: pin request.revision = VNRecognizeTextRequestRevision2. It's correct and fast on 27, but lacks some languages such as Cyrillic.
import Vision

func recognizeText(in cgImage: CGImage) async throws -> String {
    if #available(macOS 15.0, *) {
        var request = RecognizeTextRequest()
        request.recognitionLevel = .accurate
        request.usesLanguageCorrection = true
        let observations = try await request.perform(on: cgImage)
        return observations
            .compactMap { $0.topCandidates(1).first?.string }
            .joined(separator: "\n")
    } else {
        let request = VNRecognizeTextRequest()
        request.recognitionLevel = .accurate
        request.usesLanguageCorrection = true
        let handler = VNImageRequestHandler(cgImage: cgImage)
        try handler.perform([request])
        return (request.results ?? [])
            .compactMap { $0.topCandidates(1).first?.string }
            .joined(separator: "\n")
    }
}

Features that depend on text recognition, such as auto-redact PII, the OCR/QR results window, and OCR-translate, are likely affected too.

I'm happy to test a build.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions