Skip to content

fix(create): force devDependency install; add missing-binary preflight in run#1261

Draft
DaveHanns wants to merge 1 commit into
apify:masterfrom
DaveHanns:fix/f58-force-include-dev
Draft

fix(create): force devDependency install; add missing-binary preflight in run#1261
DaveHanns wants to merge 1 commit into
apify:masterfrom
DaveHanns:fix/f58-force-include-dev

Conversation

@DaveHanns

@DaveHanns DaveHanns commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

When a caller has NODE_ENV=production set — a common state after apify push (which pushes an image whose Dockerfile installs with --omit=dev), inside a Docker build, or in a shell that persists env across commands — 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, even though the success banner of apify create still points at apify run as the next step.

This PR:

  • Forces --include=dev on npm install and sets NODE_ENV=development in the child env for the post-scaffold install, so scaffolds are runnable regardless of the caller's environment (src/commands/create.ts).
  • 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 instead of leaving the user with the raw sh: <bin>: not found (src/commands/run.ts).
  • Switches the post-create git init to 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
Info: Installing dependencies...
...
Success: Actor 'tmp' was created. To run it, run "cd tmp" and "apify run".

$ cd tmp
$ apify run
Run: npm run start
> tmp@0.0.1 start
> tsx src/main.ts
sh: tsx: not found

After this PR:

  • The post-scaffold install produces a node_modules that contains tsx, so the reproducer above just works.

  • Even if the user managed to arrive at a scaffold whose devDependencies were skipped, apify run now bails out early with:

    Error: "tsx" was not found in node_modules/.bin. This usually means devDependencies
    were skipped during install (e.g. NODE_ENV=production). Run `npm install --include=dev`
    (or `pnpm install --prod=false`) and retry.
    

Test plan

  • NODE_ENV=production apify create tmp-node-env -t ts-empty — resulting node_modules/.bin contains tsx.
  • apify run in a scaffold whose node_modules/.bin/tsx has been deleted prints the new actionable error, not the raw sh: tsx: not found.
  • apify run on an unaffected scaffold (start script is node dist/main.js etc.) is unchanged.
  • apify create on a git repo host with init.defaultBranch=trunk still produces a scaffold initialised on main.

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 of apify create -t ts-* cannot hit the trap.
  • apify/apify-cli#1252apify push preflight warning when a Dockerfile has --omit=dev before npm run build that invokes tsc.
  • This PRapify create forces --include=dev + NODE_ENV=development on the post-scaffold install, so apify run works locally; plus a node_modules/.bin preflight in apify run to 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.

…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>
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.

2 participants