Hi,
I'm running the Twenty CRM Cloudron app and trying to use Logic Functions with LOGIC_FUNCTION_TYPE=LOCAL. Execution fails systematically because the local driver tries to create a .yarn directory inside the read-only /app/code, which Cloudron doesn't allow. This looks like a packaging gap rather than a Twenty bug, and the fix appears small.
Environment
- Cloudron: 9.2.0
- Twenty app package version: 1.1.0
- Twenty version: 2.9.0
- Relevant config:
LOGIC_FUNCTION_TYPE=LOCAL
What happens
When a workflow triggers a Logic Function, the server throws:
ERROR [LogicFunctionExecutorService] Logic function execution failed: ... driver=LocalDriver, mode=LIVE:
Internal Error: ENOENT: no such file or directory, mkdir '/app/code/packages/twenty-server/.yarn'
at copyYarnEngineAndBuildDependencies (.../application-package/utils/copy-yarn-engine-and-build-dependencies.js)
at LocalLayerManagerService.ensureDepsLayer (.../logic-function-drivers/drivers/local/services/local-layer-manager.service.js)
at LocalDriver.execute (.../logic-function-drivers/drivers/local.driver.js)
Root cause
The LOCAL driver's LocalLayerManagerService builds a per-function dependency layer by creating a .yarn directory inside packages/twenty-server/ and copying the Yarn engine into it. Since /app/code is mounted read-only on Cloudron, the mkdir fails.
I confirmed it's the mount, not a permission issue, even in the Web Terminal:
# id
uid=0(root) gid=0(root) groups=0(root)
# touch /app/code/_test_write
touch: cannot touch '/app/code/_test_write': Read-only file system
Two observations that point straight at the fix:
- The Yarn engine is present, but only at the monorepo root (
/app/code/.yarn, .yarnrc.yml, .corepack). It's the per-package packages/twenty-server/.yarn that's missing and can't be created.
- The package already redirects writable runtime paths under
twenty-server to /run via symlinks:
packages/twenty-server/.cache -> /run/twenty-server/cache
packages/twenty-server/.env -> /run/twenty-server/.env
So the same, proven pattern just needs to be extended to .yarn.
Suggested fix
Apply the existing symlink approach to the layer directory in the Dockerfile:
RUN ln -sf /run/twenty-server/yarn /app/code/packages/twenty-server/.yarn
and create the target early in entrypoint.sh:
mkdir -p /run/twenty-server/yarn
A couple of notes for whoever picks this up:
- The driver doesn't only create
.yarn; it then runs a Yarn install to build the deps layer, so the redirect target must stay writable and the container needs outbound network during that step. There may be one or two further writable paths the install needs, worth checking once the first mkdir is unblocked.
/run is ephemeral, so the layer would be rebuilt after a restart (same behaviour as .cache). If rebuild-on-restart is undesirable, /app/data/twenty-server/yarn would persist instead.