{"record":{"id":"0f433f10380fe25b","repo":"xpzouying/xiaohongshu-mcp","slug":"dmg-app","errorCode":null,"errorMessage":"dmg 内未找到 .app","messagePattern":"dmg 内未找到 \\.app","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"browser/browser_download.go","lineNumber":323,"sourceCode":"\t\treturn err\n\t}\n\tdefer os.RemoveAll(mountPoint)\n\n\tif out, err := exec.Command(\"hdiutil\", \"attach\", archivePath, \"-nobrowse\", \"-mountpoint\", mountPoint).CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"hdiutil attach: %v: %s\", err, out)\n\t}\n\tdefer exec.Command(\"hdiutil\", \"detach\", mountPoint, \"-quiet\").Run()\n\n\tvar appPath string\n\tentries, _ := os.ReadDir(mountPoint)\n\tfor _, e := range entries {\n\t\tif strings.HasSuffix(e.Name(), \".app\") {\n\t\t\tappPath = filepath.Join(mountPoint, e.Name())\n\t\t\tbreak\n\t\t}\n\t}\n\tif appPath == \"\" {\n\t\treturn fmt.Errorf(\"dmg 内未找到 .app\")\n\t}\n\tdstApp := filepath.Join(destDir, filepath.Base(appPath))\n\tif out, err := exec.Command(\"cp\", \"-R\", appPath, dstApp).CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"拷贝 .app: %v: %s\", err, out)\n\t}\n\t_ = exec.Command(\"xattr\", \"-dr\", \"com.apple.quarantine\", dstApp).Run()\n\treturn nil\n}\n","sourceCodeStart":305,"sourceCodeEnd":332,"githubUrl":"https://github.com/xpzouying/xiaohongshu-mcp/blob/332d196854a9eac0d2b8c2c0e3d0cc43139d724c/browser/browser_download.go#L305-L332","documentation":"After mounting the .dmg, extractDmg lists the mountpoint's top-level entries looking for a directory ending in .app. This error is thrown when no such entry exists at the root of the mounted volume, so there is nothing to copy to the destination.","triggerScenarios":"extractDmg mounts the image successfully, os.ReadDir(mountPoint) returns entries, but none has strings.HasSuffix(e.Name(), \".app\") — the volume root contains only other files/folders (docs, packages, symlinks).","commonSituations":"Upstream changed the .dmg layout (app nested in a subfolder); the mounted volume is an installer .pkg-style image rather than a drag-to-Applications image; a stale mount or wrong volume was attached (mountpoint collision); the .dmg is for a different product/version.","solutions":["Mount the .dmg manually with hdiutil attach and inspect its contents to confirm the .app location","Extend extractDmg to search nested directories (filepath.Walk) instead of only the volume root","Re-download the correct .dmg for your OS/arch if a wrong product image was fetched","Check for leftover mounts (hdiutil info) that could shadow the intended mountpoint","Update the library if upstream restructured the disk image"],"exampleFix":"// before\nentries, _ := os.ReadDir(mountPoint)\nfor _, e := range entries {\n\tif strings.HasSuffix(e.Name(), \".app\") {\n\t\tappPath = filepath.Join(mountPoint, e.Name())\n\t\tbreak\n\t}\n}\n// after — recursive search\nfilepath.Walk(mountPoint, func(p string, info os.FileInfo, err error) error {\n\tif err == nil && strings.HasSuffix(p, \".app\") && appPath == \"\" {\n\t\tappPath = p\n\t}\n\treturn nil\n})","handlingStrategy":"validation","validationCode":"// 挂载后先检查卷根目录是否包含 .app\nentries, _ := os.ReadDir(mountPoint)\nhasApp := false\nfor _, e := range entries {\n\tif strings.HasSuffix(e.Name(), \".app\") { hasApp = true }\n}\nif !hasApp { return errors.New(\"dmg 布局不含顶层 .app\") }","typeGuard":null,"tryCatchPattern":"if err := EnsureBrowser(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"dmg 内未找到 .app\") {\n\t\t// 手动挂载检查布局，必要时改用 zip/其他分发格式\n\t\treturn manualInstall()\n\t}\n\treturn err\n}","preventionTips":["Inspect the .dmg layout of the target version before automating installs","Clean up leftover mounts (hdiutil detach) to avoid attaching the wrong volume","Pin to a version whose disk-image layout is known to work","Prefer zip distribution on macOS when available to avoid dmg handling entirely"],"tags":["macos","dmg","app-bundle","extraction"],"backgroundTag":"dmg-app-not-found","analyzedSha":"332d196854a9eac0d2b8c2c0e3d0cc43139d724c","analyzedAt":"2026-09-05T22:22:55.988Z","contentChangedAt":"2026-09-05T22:22:55.988Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}