Skip to content

fix(runner): strip NODE_ENV from agent env; install gh; silence keyring warning - #26

Draft
DaveHanns wants to merge 1 commit into
chocholous:mainfrom
DaveHanns:fix/ef23-runner-env-hygiene
Draft

fix(runner): strip NODE_ENV from agent env; install gh; silence keyring warning#26
DaveHanns wants to merge 1 commit into
chocholous:mainfrom
DaveHanns:fix/ef23-runner-env-hygiene

Conversation

@DaveHanns

Copy link
Copy Markdown
Collaborator

Summary

Three small hygiene fixes to the runner container and the child-env plumbing. Each currently produces noise or a hard failure for scenarios that scaffold an Actor with apify create and then run it, or that call gh, or that log in with apify login.

Problem 1 — NODE_ENV=production leaks into the agent's shell

The runner Actor is built on apify/actor-node:24, which sets NODE_ENV=production so the runner's own npm install at image build skips devDependencies. That is correct for the runner itself.

The problem is that NODE_ENV=production is currently inherited by the agent subprocess. So when an agent scaffolds a TypeScript template and runs it:

$ apify create foo -t ts-empty
$ cd foo
$ apify run
sh: tsx: not found

Because tsx is a devDependency of the template and the apify run prestart step effectively performs npm install --omit=dev under NODE_ENV=production. tsx is required at runtime by the template's start script, so the project can't run.

Fix: add NODE_ENV to the existing APIFY_RUNTIME_KEYS_TO_STRIP list in shared/src/agents/apify-env.ts. buildChildEnv is already used everywhere the runner spawns the agent / check subprocesses, so this is a one-line change plus a covering test.

Problem 2 — OS keyring unavailable on every apify login

apify-cli prints:

OS keyring unavailable; set APIFY_DISABLE_KEYRING=1 to silence

on every login in the container. Alpine has no gnome-keyring / kwallet, so the CLI falls back to the file-backed store anyway — the warning is pure noise here.

Fix: add ENV APIFY_DISABLE_KEYRING=1 in the runner Dockerfile.

Problem 3 — gh not found (install with: brew install gh)

Three runInitPreset presets (cli_native, cli_only, none) diagnose the presence of gh and print install with: brew install gh when it's missing. The runner runs on Alpine, where the correct hint is apk add github-cli. On top of that, gh is genuinely useful — several checks and templates shell out to it — but it isn't currently installed.

Fix:

  • actors/runner/Dockerfile — install github-cli via apk add, and add it to the --version verify step.
  • shared/src/init-presets.ts — expand the hint to list apk add github-cli / apt-get install gh / brew install gh so it stays correct if the base image ever moves.

Evidence (verbatim)

[cli_only] cli_only: gh not found (install with: brew install gh)
[login] OS keyring unavailable; set APIFY_DISABLE_KEYRING=1 to silence
[apify run] Running: npm start
> start
> tsx src/main.ts
sh: tsx: not found

Test plan

  • npx tsc -p shared/tsconfig.json clean
  • npx tsc -p actors/runner/tsconfig.json clean
  • npx vitest run shared/src/__tests__/apify-env.test.ts — 9/9 pass (added case: NODE_ENV is stripped from child env)
  • Rebuild runner image, confirm gh --version works inside the container
  • Rebuild runner image, confirm no OS keyring unavailable in apify login output
  • From an agent shell spawned by the runner: apify create foo -t ts-empty && cd foo && apify run exits 0

Notes

Each of the three fixes stands on its own and could be split into three PRs if reviewers prefer — grouped here because they all fall under "runner env hygiene" and share the same root context.


Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.

…lence keyring warning

Three small hygiene fixes to the runner container / child-env plumbing that
each cause noisy or hard failures for scenarios that scaffold an Actor via
`apify create` and then run it.

1. `shared/src/agents/apify-env.ts` — add `NODE_ENV` to the list of env vars
   stripped from the agent subprocess env. The `apify/actor-node` base image
   sets `NODE_ENV=production` so the runner's own `npm install` (executed at
   image build) skips devDependencies. When that value leaks into the agent's
   shell, any scaffolded project it runs inherits it too — so
   `apify create foo -t ts-empty && cd foo && apify run` fails with
   `sh: tsx: not found` because `npm install --omit=dev` drops `tsx` even
   though the template lists it as a devDependency it needs at runtime.
   Test added alongside the existing stripped-keys coverage.

2. `actors/runner/Dockerfile` — install `github-cli` via apk and add it to
   the CLI verify step. Also add `ENV APIFY_DISABLE_KEYRING=1` so the
   apify-cli stops printing `OS keyring unavailable; set
   APIFY_DISABLE_KEYRING=1 to silence` on every login inside the container
   (Alpine has no gnome-keyring / kwallet, so it falls back to a file store
   anyway — the warning is pure noise here).

3. `shared/src/init-presets.ts` — the `which gh` diagnostic in three presets
   suggested `brew install gh` even though the runner runs on Alpine. Expand
   the hint to list `apk add github-cli / apt-get install gh / brew install gh`
   so it's correct on the actual host (and stays useful if the runner ever
   moves to a Debian-based base image).

Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@DaveHanns
DaveHanns marked this pull request as draft July 5, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant