fix(create): force devDependency install; add missing-binary preflight in run#1261
Draft
DaveHanns wants to merge 1 commit into
Draft
fix(create): force devDependency install; add missing-binary preflight in run#1261DaveHanns wants to merge 1 commit into
DaveHanns wants to merge 1 commit into
Conversation
…t in run When a caller has `NODE_ENV=production` set — a common state after `apify push` (which pushes an image whose Dockerfile installs with `--omit=dev`) or inside a Docker build — the `npm install` that `apify create` runs after unpacking the template inherits that env and skips devDependencies. TypeScript templates rely on devDependencies (`tsx`, `typescript`, etc.), so `apify run` on the resulting scaffold fails immediately with a bare `sh: tsx: not found`, while the success banner of `apify create` still points at `apify run` as the next step. This change: - Forces `--include=dev` on npm and sets `NODE_ENV=development` in the child env for the post-scaffold install, so scaffolds are runnable regardless of the caller's environment. - Adds a preflight in `apify run` that, for `npm run <script>` style entrypoints, checks whether the script's leading binary exists in `node_modules/.bin`. On miss, it emits an actionable error (`"tsx" was not found in node_modules/.bin. This usually means devDependencies were skipped ...`) instead of leaving the user with the raw `sh: tsx: not found`. - Uses `git init -b main` (with a fallback for older git) so scaffolded projects start on `main` regardless of the host's `init.defaultBranch` config. Reproducer: NODE_ENV=production apify create tmp -t ts-empty cd tmp && apify run # before: sh: tsx: not found # after: "tsx" was not found in node_modules/.bin. ... Surfaced during an evaluation of Apify surfaces for agent-driven Actor development. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a caller has
NODE_ENV=productionset — a common state afterapify push(which pushes an image whose Dockerfile installs with--omit=dev), inside a Docker build, or in a shell that persists env across commands — thenpm installthatapify createruns after unpacking the template inherits that env and skipsdevDependencies. TypeScript templates rely ondevDependencies(tsx,typescript, etc.), soapify runon the resulting scaffold fails immediately with a baresh: tsx: not found, even though the success banner ofapify createstill points atapify runas the next step.This PR:
--include=devonnpm installand setsNODE_ENV=developmentin the child env for the post-scaffold install, so scaffolds are runnable regardless of the caller's environment (src/commands/create.ts).apify runthat, fornpm run <script>style entrypoints, checks whether the script's leading binary exists innode_modules/.bin. On miss, it emits an actionable error instead of leaving the user with the rawsh: <bin>: not found(src/commands/run.ts).git inittogit init -b main(with a fallback for older git), so scaffolded projects start onmainregardless of the host'sinit.defaultBranchconfig.Reproducer
After this PR:
The post-scaffold install produces a
node_modulesthat containstsx, so the reproducer above just works.Even if the user managed to arrive at a scaffold whose
devDependencieswere skipped,apify runnow bails out early with:Test plan
NODE_ENV=production apify create tmp-node-env -t ts-empty— resultingnode_modules/.bincontainstsx.apify runin a scaffold whosenode_modules/.bin/tsxhas been deleted prints the new actionable error, not the rawsh: tsx: not found.apify runon an unaffected scaffold (start script isnode dist/main.jsetc.) is unchanged.apify createon a git repo host withinit.defaultBranch=trunkstill produces a scaffold initialised onmain.Related — coordinated remediation stack
Four defense layers, each covering a different failure mode:
apify/actor-templates— ts-* Dockerfiles ship a multi-stage build (already in master via #592, Dec 2025). Users ofapify create -t ts-*cannot hit the trap.apify/apify-cli#1252—apify pushpreflight warning when a Dockerfile has--omit=devbeforenpm run buildthat invokestsc.apify createforces--include=dev+NODE_ENV=developmenton the post-scaffold install, soapify runworks locally; plus anode_modules/.binpreflight inapify runto surface an actionable error if the trap fires anyway.apify/apify-docs#2716— docs callout on the Source-code page for the direct-docker build/ search-fallback case.Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.