Skip to content

HubApi default downloadBase triggers macOS TCC "Documents folder" prompt for apps that never use the Hub #339

@adamsro

Description

@adamsro

Hi, thanks for publishing this library!

Here's a note from Claude. A patch from Claude did fix this issue for my setup.

Problem

HubApi.init() defaults downloadBase to ~/Documents/huggingface when no explicit path is provided:

// Sources/Hub/HubApi.swift:163-164
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
self.downloadBase = documents.appending(component: "huggingface")

On macOS Sequoia+, resolving .documentDirectory triggers a TCC consent prompt: "App would like to access files in your Documents folder."

This affects any app that links the Tokenizers module — even if the app never downloads from the Hub. The static let shared = HubApi() singleton is lazily initialized when Swift evaluates default parameters like hubApi: HubApi = .shared in AutoTokenizer.from(modelFolder:), which is enough to trigger the prompt.

Impact

  • Apps that only use Tokenizers for local model loading get an unexpected Documents folder permission prompt
  • Users may deny the prompt, causing confusion
  • The downloadBase directory (~/Documents/huggingface) is never actually used in these cases

Suggested fix

Change the default downloadBase from .documentDirectory to a non-TCC-protected location. Options:

  1. ~/.cache/huggingface — matches Python huggingface_hub convention, matches swift-huggingface's CacheLocationProvider.defaultCacheDirectory() on non-sandboxed macOS
  2. .applicationSupportDirectory — standard macOS app data location
  3. .cachesDirectory (~/Library/Caches/) — simplest change but subject to system purging

Option 1 seems most consistent with the ecosystem. Any change would need migration consideration for existing users who have snapshots in ~/Documents/huggingface/.

Reproduction

  1. Create a macOS app that depends on swift-transformers (Tokenizers product)
  2. Call AutoTokenizer.from(modelFolder: someLocalPath) without passing hubApi:
  3. On macOS Sequoia+, the app shows a "Documents folder" TCC prompt on first run

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions