From 59dff3d36d62d2ae168b78042f2048c703ebdcf8 Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Fri, 1 May 2026 11:45:55 -0700 Subject: [PATCH] fix(entrypoint): pre-create /workspace/.molecule/chat-uploads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fresh-tenant signup hits "Upload failed: failed to prepare uploads dir" on the first chat attachment (reported on hongming.moleculesai.app 2026-05-01T18:30Z). Root cause is that workspace/internal_chat_uploads.py runs `mkdir -p /workspace/.molecule/chat-uploads` as the agent user, but the volume's `.molecule` subdir surfaces root-owned in some race windows (volume cache + new mount + RW remount during reboot/redeploy). Pre-creating the directory tree as root in the entrypoint, BEFORE gosu drops to agent, eliminates the class entirely — the upload handler's `mkdir(parents=True, exist_ok=True)` is a no-op on the common path and the failure mode it currently surfaces no longer exists. Idempotent: works on fresh volumes (creates) and reused volumes (no-op + chown re-asserts ownership in case a prior process changed it). Co-Authored-By: Claude Opus 4.7 (1M context) --- entrypoint.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/entrypoint.sh b/entrypoint.sh index 396f2a0..b4e4fb2 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -23,6 +23,17 @@ if [ "$(id -u)" = "0" ]; then if [ -n "$first_entry" ] && [ "$(stat -c '%u' "$first_entry" 2>/dev/null)" = "0" ]; then chown -R agent:agent /workspace 2>/dev/null fi + # Pre-create /workspace/.molecule/chat-uploads so the upload + # handler in workspace/internal_chat_uploads.py never has to + # mkdir as agent inside a root-owned tree. Without this the + # first upload after a fresh provision fails with "failed to + # prepare uploads dir" because the volume mount comes up with + # root-owned `.molecule` whenever a sibling subsystem (e.g. an + # adapter writing telemetry, or a workspace runtime that ran + # before the chown landed) raced ahead. Idempotent: a re-run + # finds the dir already there, mode 0755 / agent:agent. + mkdir -p /workspace/.molecule/chat-uploads 2>/dev/null || true + chown -R agent:agent /workspace/.molecule 2>/dev/null || true fi # Claude Code session directory — mounted at /root/.claude/sessions by # the platform provisioner. Symlink it into agent's home so the SDK