Skip to content

[Bug] Packaged app can crash with masked persisted workspace cache error #156

@Astro-Han

Description

@Astro-Han

What happened?

PawWork v0.2.5 packaged app showed a renderer error page while opening or rendering a session/workspace view:

Error: Failed to create persisted cache
    at ensureChild (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/main-CpucilYi.js:68422:23)
    at Object.child (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/main-CpucilYi.js:68504:24)
    at file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/main-CpucilYi.js:69475:23
    at get data (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/main-CpucilYi.js:69738:16)
    at Object.fn (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/session-DGl7U4CN.js:25801:27)
    at runComputation (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/styles-C-a255bR.js:468:22)
    at updateComputation (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/styles-C-a255bR.js:451:3)
    at runTop (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/styles-C-a255bR.js:546:7)
    at runQueue (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/styles-C-a255bR.js:618:42)
    at completeUpdates (file:///Applications/PawWork.app/Contents/Resources/app.asar/out/renderer/assets/styles-C-a255bR.js:574:5)

Local source inspection maps the top frame to packages/app/src/context/global-sync/child-store.ts, where ensureChild() creates the workspace-level vcs persisted store:

const vcs = runWithOwner(input.owner, () =>
  persisted(
    Persist.workspace(directory, "vcs", ["vcs.v1"]),
    createStore({ value: undefined as VcsInfo | undefined }),
  ),
)
if (!vcs) throw new Error(input.translate("error.childStore.persistedCacheCreateFailed"))

persisted() normally returns a tuple, so the visible error is masking an earlier synchronous exception from inside the runWithOwner(...persisted...) callback. Solid's runWithOwner() can route callback errors through the owner error handling path and return undefined; PawWork then replaces the original cause with the generic translated error. The generic Failed to create persisted cache message is therefore the symptom, not the root cause.

This is separate from #145's startup hang: the latest local ~/Library/Logs/PawWork/main.log shows the app reached loading task finished, init step { phase: 'done' }, and server ready. The main-process log did not include the renderer storage cause. The recurring updater app-update.yml warning in the same log appears unrelated to this renderer crash.

Updated diagnosis

After extracting /Applications/PawWork.app/Contents/Resources/app.asar from the affected v0.2.5 install, the packaged renderer still uses the old OpenCode storage names:

const GLOBAL_STORAGE = "opencode.global.dat"
return `opencode.workspace.${head}.${sum}.dat`

The storage namespace rename to pawwork.global.dat / pawwork.workspace.*.dat landed after v0.2.5 and should be included in v0.2.6. Therefore, do not attribute this specific observed v0.2.5 crash to the later pawwork.* storage rename. The relevant v0.2.5 question is what original synchronous exception was hidden behind Failed to create persisted cache.

The stronger current hypothesis is a bad workspace directory value reaching ensureChild(). In the packaged bundle, the path is:

get data() {
  return current()[0]
}

where current() calls globalSync.child(sdk.directory), and ensureChild(directory) only logs when directory is falsy:

if (!directory) console.error("No directory provided")

It then continues into Persist.workspace(directory, "vcs", ...). workspaceStorage(dir) immediately calls dir.slice(0, 12), so if directory is undefined, null, or otherwise not a string, it will synchronously throw before persisted() can return. That synchronous throw is then masked as Failed to create persisted cache by the runWithOwner() fallback path.

This does not prove the bad-directory hypothesis yet, because the original exception is currently hidden. It does make a broad app-data permission explanation less likely for this v0.2.5 report.

What did you expect to happen?

The session/workspace view should keep rendering, recover, or at minimum show/report the original failure with enough context to diagnose it. A generic Failed to create persisted cache error page is not actionable.

What actually happened?

The packaged app entered a renderer error page before the session view could render. The visible error only identifies the first child-store cache (vcs) and hides the real synchronous failure.

Investigation notes

  • Installed app: /Applications/PawWork.app, version 0.2.5.
  • App data directory: ~/Library/Application Support/ai.pawwork.desktop.
  • The affected packaged renderer still uses opencode.global.dat and opencode.workspace.*.dat.
  • The current dev / v0.2.6 line uses pawwork.global.dat and pawwork.workspace.*.dat, so storage namespace rename should already be covered for the next release line.
  • Manual local probing showed the app data directory itself is writable; this does not prove the packaged renderer storage path is healthy, but it makes a broad directory-permission failure less likely.
  • The most useful next diagnostic is preserving the original cause, directory, storage, and key when child-store persisted cache creation fails.
  • No existing issue was found for the exact Failed to create persisted cache symptom.

Suggested fix direction

  • Add an explicit guard in ensureChild(directory) for non-string or empty directory values. Do not continue into Persist.workspace(...) after only logging No directory provided.
  • Preserve and surface the original cause when runWithOwner(...persisted...) fails, including the directory, persistence target storage name, key, and original error/cause when available.
  • Add a regression test for a bad directory value reaching ensureChild() so it fails with an actionable error instead of Failed to create persisted cache.
  • Add a regression test that simulates workspace persisted cache initialization failure and verifies the diagnostic is not replaced by only Failed to create persisted cache.
  • After the true cause is visible, decide whether the production fix belongs in the route/SDK directory lifecycle, child-store input validation, or desktop storage handling.

PawWork version

v0.2.5 packaged macOS app.

OS version

macOS on the local development machine.

Can you reproduce it again?

Not yet. Observed from the packaged app error page and investigated from the stack trace plus local source and extracted packaged renderer bundle.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityappApplication behavior and product flowsbugSomething isn't workingplatformElectron shell, OS integration, packaging, updater, signing, paths, and permissions

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions