CI has never passed: containerized job dies on /var/run symlink in node:20-bullseye #6

Closed
opened 2026-08-24 22:46:36 -05:00 by jason · 1 comment
Owner

CI has failed on every run since the repo was created — 19 for 19, from run #1 (b7501252, 2026-07-16) through run #19 (efc2238, 2026-08-24). That includes run #8, which was the v0.5.0 release commit. The library has never had a green build.

Symptom

The job dies during container setup, before a single workflow step executes:

Start image=node:20-bullseye
docker create image=node:20-bullseye ...
Started container: 49163bccf538...
Writing entry to tarball workflow/event.json len:5126
Extracting content to '/var/run/act/'
failed to copy content to container: Error response from daemon:
  mkdirat var/run/act: path escapes from parent

Older runs show the same failure with a slightly different message: mkdirat var/run: file exists.

Root cause

.gitea/workflows/ci.yml declares runs-on: ubuntu-latest. act_runner resolves that label to the node:20-bullseye image and runs the job inside a container. In that Debian image /var/run is a symlink to /run, so when act tries to extract its workflow payload to /var/run/act/, Docker's archive extraction refuses to write a path through a symlink that leaves the parent directory — hence path escapes from parent.

This is not a code problem and not a runner-wide outage. npm run check and npm pack --dry-run both pass locally at efc2238. Every other repo on unraid-runner-02 is green — table, memer, depot, fleet, slate — and every one of them declares runs-on: host. ui-kit is the only repo asking for a containerized job, so it is the only repo hitting this.

Fix

Switch to runs-on: host, matching the rest of the fleet. ui-kit builds no image and deploys nothing — it is consumed via git+https://...#vX.Y.Z, where the consumer's own npm install runs the prepare build. There is nothing here that needs container isolation; the job just needs Node and the repo.

Note on the checks themselves

Worth stating why the job is more than a syntax check, since that came up: consumers install this package straight from a git tag, so prepare -> npm run build executes on their machine at install time. A broken build here is a broken install everywhere downstream, which is why the full npm run check (tokens drift, typecheck, tests, build, demo/showcase compile, impeccable) plus a npm pack --dry-run file-list smoke test is the right gate for this repo rather than a lint pass.

CI has failed on **every run since the repo was created** — 19 for 19, from run #1 (`b7501252`, 2026-07-16) through run #19 (`efc2238`, 2026-08-24). That includes run #8, which was the `v0.5.0` release commit. The library has never had a green build. ### Symptom The job dies during container setup, before a single workflow step executes: ``` Start image=node:20-bullseye docker create image=node:20-bullseye ... Started container: 49163bccf538... Writing entry to tarball workflow/event.json len:5126 Extracting content to '/var/run/act/' failed to copy content to container: Error response from daemon: mkdirat var/run/act: path escapes from parent ``` Older runs show the same failure with a slightly different message: `mkdirat var/run: file exists`. ### Root cause `.gitea/workflows/ci.yml` declares `runs-on: ubuntu-latest`. act_runner resolves that label to the `node:20-bullseye` image and runs the job inside a container. In that Debian image `/var/run` is a **symlink to `/run`**, so when act tries to extract its workflow payload to `/var/run/act/`, Docker's archive extraction refuses to write a path through a symlink that leaves the parent directory — hence `path escapes from parent`. This is not a code problem and not a runner-wide outage. `npm run check` and `npm pack --dry-run` both pass locally at `efc2238`. Every other repo on `unraid-runner-02` is green — `table`, `memer`, `depot`, `fleet`, `slate` — and every one of them declares `runs-on: host`. ui-kit is the only repo asking for a containerized job, so it is the only repo hitting this. ### Fix Switch to `runs-on: host`, matching the rest of the fleet. ui-kit builds no image and deploys nothing — it is consumed via `git+https://...#vX.Y.Z`, where the consumer's own `npm install` runs the `prepare` build. There is nothing here that needs container isolation; the job just needs Node and the repo. ### Note on the checks themselves Worth stating why the job is more than a syntax check, since that came up: consumers install this package straight from a git tag, so `prepare` -> `npm run build` executes on *their* machine at install time. A broken build here is a broken install everywhere downstream, which is why the full `npm run check` (tokens drift, typecheck, tests, build, demo/showcase compile, impeccable) plus a `npm pack --dry-run` file-list smoke test is the right gate for this repo rather than a lint pass.
Author
Owner

Fixed in 1dc64c7runs-on: ubuntu-latest -> runs-on: host.

Run #20 is green. First passing build in the repo's history, after 19 consecutive failures.

The job now executes every step rather than dying at container setup:

Test Files  2 passed (2)
> impeccable detect src/
npm notice version: 0.5.1
npm notice package size: 48.9 kB
npm notice total files: 19
Job succeeded

That output matches a local npm run check + npm pack --dry-run byte for byte, so the gate is now actually gating.

One thing worth recording for the next person who reaches for a container here: swapping the job image would not have fixed this. /var/run is a symlink to /run on Ubuntu just as it is on Debian, so catthehacker/ubuntu:act-latest would hit the identical path escapes from parent failure. On this act_runner build (v0.2.11) any containerized job fails the same way — which is why all five other repos on the runner were already on runs-on: host. That is the supported path here, not a workaround.

Note the v0.5.1 tag itself points at efc2238, one commit before this fix, so the release never got a green run under its own tag — but 1dc64c7 is a direct descendant with identical library content, so everything in v0.5.1 is covered by run #20.

Fixed in 1dc64c7 — `runs-on: ubuntu-latest` -> `runs-on: host`. **Run #20 is green.** First passing build in the repo's history, after 19 consecutive failures. The job now executes every step rather than dying at container setup: ``` Test Files 2 passed (2) > impeccable detect src/ npm notice version: 0.5.1 npm notice package size: 48.9 kB npm notice total files: 19 Job succeeded ``` That output matches a local `npm run check` + `npm pack --dry-run` byte for byte, so the gate is now actually gating. One thing worth recording for the next person who reaches for a container here: swapping the job image would **not** have fixed this. `/var/run` is a symlink to `/run` on Ubuntu just as it is on Debian, so `catthehacker/ubuntu:act-latest` would hit the identical `path escapes from parent` failure. On this act_runner build (v0.2.11) any containerized job fails the same way — which is why all five other repos on the runner were already on `runs-on: host`. That is the supported path here, not a workaround. Note the `v0.5.1` tag itself points at efc2238, one commit before this fix, so the release never got a green run under its own tag — but 1dc64c7 is a direct descendant with identical library content, so everything in v0.5.1 is covered by run #20.
jason closed this issue 2026-08-24 22:49:08 -05:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jason/ui-kit#6