Skip to content

fix(sidecar): old chats are not imported on a launch that cannot read ~/Documents yet #202

Open

Description

@AojdevStudio

Found while installing the durable sidecar stack (#201, head 0e89dae) over ~/Applications/Materialize 3D Chat.app on Ossie's MacBook.

That install had a new code identity, so macOS had not yet given it access to ~/Documents. At startup the sidecar's import of old chats (legacyProjects in sidecar/src/legacy.ts) saw no projects folder and imported nothing. No message said why.

The import code itself works on that machine's real chat. The same bundled sidecar, run on its own with a scratch store, logged imported 1 chats from before the store: 2026-11-06-let-s-make-a-2x2-cube.

Once access is allowed, the next launch imports the chat, because the import skips only chats already in the store. An update from a Developer ID release keeps its identity and its grant, so the usual update path is not affected.

What to do:

  • Tell an unreadable projects folder (EPERM) apart from a missing one, and log it.
  • Import again once the folder becomes readable, without a relaunch.

Activity

  1. pullfrog commented on Nov 7, 2026

    @pullfrog

    No duplicate found. This is a follow-up to #201, which introduces the legacy importer; the relevant code is currently on that PR’s branch, not main.

    Diagnosis
    In sidecar/src/legacy.ts, the initial existsSync(projectsDir) check can hide a permission denial as “missing.” The root statSync/readdirSync calls are also outside the per-project error handler. In sidecar/src/app.ts, import runs only once before the pipe opens, so granting access later cannot trigger recovery. Store.importLegacy() already checks project IDs inside each commit, providing the required duplicate protection.

    Implementation Plan

    1. Replace the permission-masking existence checks with error-aware filesystem reads. Keep missing/non-directory paths harmless; distinguish and log EPERM/EACCES with the affected path, and return enough status to retry unreadable paths. Preserve per-project isolation for malformed files.
    2. Keep the initial import before serving requests. If access is denied, continue startup and schedule non-overlapping, low-frequency retries. Recompute known project IDs before each attempt, suppress repeated identical warnings, and cancel/drain retries before closing the store.
    3. Notify the window after a retry commits new projects. Extend the sidecar event contract and StudioApp.tsx to refresh the project list without resetting the selected chat or unsaved draft; it currently has no project-change subscription.
    4. Add regression tests for denial followed by readability in the same process, missing/non-directory paths, repeated retries without duplicate chats or transcript rereads, and clean shutdown. Inject permission errors for deterministic tests rather than relying solely on chmod. Run sidecar tests/typecheck and the Studio tests, then verify the actual macOS Documents permission flow: grant access while the app stays open and confirm the old chat appears once.

    No code changes or PR created.

    Pullfrog  | Implement a fix ➔ | View workflow run | via Pullfrog | Using gpt-6.1-sol | 𝕏

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

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions