Skip to main content

Start with verbose output

Repeat the failing command with --verbose to include debug logs and error stacks:
Check the runtime with node --version. Use Node.js 24 or 26+ when running the repository and Vitest plugin; Vitest 5 excludes Node.js 25.

CLI not found or the wrong package runs

Install @isox-sh/cli in your workspace before running npx isox:
The npm package is @isox-sh/cli, while its executable is isox. For pnpm and Yarn installations, use pnpm exec isox or yarn isox. See installation options.

Workspace not found

Isox searches from the current directory upward for isox.json. Run npx isox init at the intended workspace root, then run commands from that directory or its descendants. A marker in a nested directory creates a separate workspace boundary. init refuses to overwrite an existing marker. Edit that file directly when changing settings in an initialized workspace.

Project or command not found

Check that the project has a project.json with a unique name and that the command is defined under targets. Check that its path is not excluded by .gitignore or .isoxignore, symlinked, or inside a nested workspace. Discovery uses cached definitions for single-project commands. Refresh them after edits:
Names are case-sensitive. The directory name is used when name is omitted. For a command named init, add, run, reset, affected, plan, or run-many, use isox run web:reset (substituting your command) to avoid the CLI’s reserved names.

Why does run-many rebuild the workspace every time?

run-many deliberately reads fresh project.json files and rewrites .isox/workspace.json before selecting tasks. Its child commands then load that definitions cache. This refresh does not analyze source imports. An executor such as js:tsc can separately request dependency analysis and use discovery.json. affected and plan also refresh project definitions on every invocation.

Why did a comment edit change the sources SHA?

The per-project sources SHA in discovery.json fingerprints file paths, identities, sizes and timestamps. It does not hash only imports. A body or comment edit can invalidate that project’s entry on the next dependency request. Isox reanalyzes the project’s included sources, not just the edited file; unchanged dependency projects can still reuse their results. Tests and declaration files count unless excluded by discovery rules or compiler output ownership. Only dependency requests perform these checks. Ordinary command loading reads workspace.json directly. Source edits do not require isox reset, and a valid dependency cache does not skip compilation or other task execution.

Why does discovery.json contain paths outside the workspace?

The reads entries record TypeScript module-resolution probes. A directory entry such as {"path":"/Users/node_modules","kind":"directory","value":false} means that TypeScript checked whether the directory exists and it did not. Package lookup can check node_modules directories up the ancestor chain; this does not recursively scan them. File/content and real-path probes are recorded too. Build-time dependency analysis currently includes project test files. A test’s require.resolve() can therefore produce probes unrelated to the emitted build files. These records are checked only when dependency analysis is requested. See cache fields and invalidation.

Executor package cannot be loaded

Install executor packages where they resolve from the workspace root. For example, js:tsc requires @isox-sh/js:
Under pnpm, use pnpm add -Dw @isox-sh/js from the workspace root. Build local plugins before using them and verify that executors.json points to compiled JavaScript. The plugin layout guide shows the manifest structure. The built-in core:run-command falls back to the CLI’s core dependency. A directly installed workspace copy takes precedence, including when that copy is invalid.

An option or configuration is rejected

Execution commands forward unknown flags as executor options. Check the executor’s supported options when one is rejected; each executor decides whether to validate them. For TypeScript watch mode, use isox build web --watch, or put watch: true in a named configuration and run isox build web --config=watch. Configuration names must exist on the selected command. Overrides replace nested objects and arrays rather than merging them recursively. See named configurations.

TypeScript cannot resolve a workspace dependency

Build the dependency with declarations enabled before building its consumer. The TypeScript executor remaps cross-project source aliases to built declarations using the dependency’s compiler configuration. Verify its rootDir, outDir, and any declarationDir match the files it emits. The builder validates cached dependency analysis against source metadata, configuration and resolution inputs, and reanalyzes invalid entries. For the Isox repository itself, pnpm bootstrap prepares the CLI, executors, and prerequisite outputs from a clean checkout.

A source file is not under rootDir

Keep editor and build configs separate when workspace aliases point to another project’s source. The editor config can use the workspace as rootDir with noEmit: true; the build config can keep rootDir: "./src" and its own outDir. Set the build target’s options.tsConfig to that build config. Build dependencies first with declarations enabled. js:tsc remaps their source aliases to declarations during compilation. Direct tsc invocations do not run this Isox remapping. Projects created with isox init @isox-sh/js <path> already have separate editor and build configs. See TypeScript setup.

Project dependency cycle

The error lists a chain such as app -> workspace -> app. Check both explicit dependencies and inferred relationships: imports in tests and local package devDependencies count too. Selection filters, including plan.enabled: false and ci=off, do not remove graph edges or bypass cycle validation. For an unexpected edge through compiled output, make sure each build target’s options.tsConfig points to the config that declares its output directory. For a root project, imports of root-level scripts or configuration belong to that project. Keep repository-wide tests with the root tooling they exercise, and keep package tests focused on their package. A root project can depend on packages without those packages needing to depend on the root. Affected planning reads current project definitions and infers dependencies. isox plan --target=test validates that graph without running tests; --all skips dependency inference.

Affected selection is larger than expected

Changes to root manifests, lockfiles, shared TypeScript configuration, and .github affect all projects. Other files outside every project are ignored unless matched by affected.globalFiles. Dependencies propagate changes to their transitive dependents before command and tag filtering. Inspect the selection without running tasks:
Use narrow affected.globalFiles globs for additional shared tooling and affected.ignoreFiles to exclude files before global and project matching. See what counts as affected.

Affected selection is empty or Git history is missing

Local unstaged and staged changes require --uncommitted; non-ignored untracked files require --untracked. Projects must have the requested command and pass the tag filters. plan.enabled: false or a ci=off tag excludes a project from normal selection. For CI, use a checkout with fetch-depth: 0 in the planning job. Missing revisions are errors. On non-PR events the actions compare against the nearest reachable Git tag; a tag on HEAD produces an empty plan. Supply an earlier base or set affectedOnly: false when rebuilding that release.

A TypeScript output lock remains after a forced stop

Stop active builds and recover any needed backups from .isox/tasks before running isox reset. Reset removes stale locks and reservations, but also deletes those backups and all output ownership records. See output recovery. Reset leaves compiled output in place. Uncached TypeScript builds preserve files whose ownership records were removed; cacheable targets still replace their declared output directories on the next run, including with --skip-cache.

Report a reproducible issue

Include the command, verbose output, Node.js and package versions, the relevant project.json and tool configuration, and a small reproduction in a GitHub issue. Remove credentials and private environment values from logs before sharing them.