#1771·Keka

[BUG] Crash in moveExtractionContents: — URLByAppendingPathComponent: with nil lastPathComponent (v1.6.7, macOS 27)

Author: NoasamaaCreated Aug 12, 2026Updated Aug 12, 2026
Labelsbugcoreworks for memore info needed

Brief description

Keka crashes (SIGABRT) when finishing an extraction. The uncaught exception is raised inside -[NSURL URLByAppendingPathComponent:] because the path component argument is nil.

This happens after extraction, while moving/finalizing extraction contents — not during the archive tool process itself.

Keka version

  • Keka 1.6.7 (5729) — latest GitHub release as of 2026-06-30
  • Distribution: notarized Developer ID build from keka.io (TeamIdentifier=4FG648TM2A)
  • Universal binary, crash on arm64 slice

macOS version

  • macOS 27.0 (26A5406e) (Apple Silicon, Mac17,8)
  • Hardened Runtime enabled

Steps to reproduce

  1. Install Keka 1.6.7 (fresh / sandboxed install with little or no File Access bookmarks configured).
  2. Double-click an archive (or open with Keka) so extraction starts immediately.
  3. Keka aborts shortly after launch / during finalize (seen within ~9s of process start).

Observed 4 identical crashes in a few minutes (Keka-2026-08-12-182916183033.ips).

Expected behaviour

Extraction completes (or fails with a recoverable error / access prompt). Keka should not abort.

Actual behaviour

Process terminates:

  • EXC_CRASH / SIGABRT
  • asi: abort() called (uncaught Objective-C exception)
  • Exception originates from: -[NSURL(NSURLPathUtilities) URLByAppendingPathComponent:]

Apple raises when the component argument is nil: *** -[NSURL URLByAppendingPathComponent:]: component, components, or pathExtension cannot be nil.

Evidence (crash stack)

lastExceptionBacktrace / faulting main thread (summarized):

objc_exception_throw
-[NSURL URLByAppendingPathComponent:]
Keka  moveExtractionContents:   (+0xc8 / imageOffset 123752)
Keka  finalizeTask              (+0x1b0 / imageOffset 259608)
Keka  (caller around applyQuarantine path / finalize, imageOffset 245828)
_dispatch_client_callout / main queue

Four consecutive reports share the same exception site and offsets.

Binary analysis (v1.6.7 arm64)

ObjC method mapping from the binary:

Image offset Method
0x10001e2a0 -moveExtractionContents:
0x10003f468 -finalizeTask
Crash return addr 0x10001e368 inside moveExtractionContents: right after the throwing call

Reconstructed call sequence at the throw site in -moveExtractionContents: (selectors resolved from __objc_stubs / selrefs):

objc
// package = [task package]  (or equivalent receiver chain)
NSURL *destinationPath = package.destinationPath;              // base (non-nil in crash path)
// ...
NSString *component =
    package.sourcePath
           .URLByDeletingPathExtension
           .lastPathComponent;                                 // can be nil

NSURL *url = [destinationPath URLByAppendingPathComponent:component]; // THROWS if component == nil

Relevant selectors confirmed on the path:

  • package
  • packageTemporaryPath
  • destinationPath
  • sourcePath
  • URLByDeletingPathExtension
  • lastPathComponent
  • URLByAppendingPathComponent: ← throw
  • also nearby: useInputNameAsIntermediateFolder, tarballWithTwoExtensions

So the crash is not a random memory corruption; it is a missing nil-check on the intermediate folder / output name derived from sourcePath.

Likely conditions for component == nil

From Foundation behavior / sandbox setup on this machine:

  1. sourcePath is nil (bookmark / security-scoped access failed; then the whole chain returns nil, and URLByAppendingPathComponent: throws).
  2. Or sourcePath is an NSURL with no path, so lastPathComponent is nil after URLByDeletingPathExtension.

On the crashing system:

  • Keka is sandboxed (com.apple.security.app-sandbox).
  • App Group container 4FG648TM2A.group.com.aone.keka was effectively empty (no persisted File Access bookmarks).
  • Preferences only had Sparkle keys — no saved extract destination.

That matches “open archive with little file access → finalize still calls moveExtractionContents: with a bad/missing sourcePath”.

Suggested fix (for maintainers)

In -moveExtractionContents: (and any similar builders):

objc
NSURL *source = package.sourcePath;
NSString *component = source.URLByDeletingPathExtension.lastPathComponent;
if (component.length == 0) {
    // fallback: temporary package name, UUID, or skip rename and surface a file-access error
    return; // or handle error without throwing
}
NSURL *url = [destinationPath URLByAppendingPathComponent:component];

Also guard:

  • destinationPath == nil
  • failed security-scoped bookmark resolve

Optional: prefer URLByAppendingPathComponent:isDirectory: and avoid building paths when File Access / source URL is unavailable — ask for access instead of finalizing.

Workaround for users

  1. Open Keka first → Preferences → File Access → grant Home / Full Disk access.
  2. Prefer drag-and-drop into the Keka window over double-click until fixed.
  3. Or extract with Archive Utility / ditto as a temporary bypass.

Notes

  • Latest release notes for 1.6.x fix other macOS 26 issues (default uncompressor, BSDTAR, ISO, etc.) but do not mention this finalize / moveExtractionContents: crash.
  • This repository does not contain the app sources, so a code PR is not possible from the community side; filing here for maintainers.

Attachments

Happy to attach full .ips reports (Keka-2026-08-12-*.ips) if useful. Key fields:

  • app_version: 1.6.7 / build_version: 5729
  • exception: EXC_CRASH (SIGABRT)
  • termination: Abort trap: 6 by Keka
  • cpuType: ARM-64

Thanks!