Setup

These entries cover the tools on your machine that a build, an upload, or a local run uses. What your computer needs lists those tools and the versions the platform runs.

PowerShell says running scripts is disabled when npm runs

Cause. In PowerShell, npm runs the script npm.ps1, which Node.js installs beside npm.cmd. Windows PowerShell's default execution policy, Restricted, blocks every script, so PowerShell blocks npm before npm starts. npx is blocked the same way.

Check. The error mentions npm.ps1 and says that running scripts is disabled on this system. Get-ExecutionPolicy returns Restricted, and the same command runs when you call it as npm.cmd.

Remedy. Run npm.cmd with the same arguments, and npx.cmd in place of npx. Each line of the turnzero-cloud command that a tool call returns has a Windows form, which already has npx.cmd. A line that no tool call returns, such as the hash line or the unattended deploy line, is written with npx.cmd by hand. In the folder that contains package.json, npm.cmd install installs the dependencies and writes the lockfile the artifact includes. No test checks this sample.

npm.cmd install

A .ps1 script your tool writes meets the same block, since the execution policy is your machine's. Run it for one process with powershell -NoProfile -ExecutionPolicy Bypass -File <script>, which leaves the machine's policy as it is. Or run the script's commands inline in the session instead.

Windows PowerShell lists the other changes the commands on these pages need there, a zip you build yourself among them.

The deploy line prints an npm notice, and PowerShell shows it as an error

Cause. npm prints its own notices, such as a new version being available, on standard error. Each line of the turnzero-cloud command runs through npx, the deploy line that a deploy call returns and the hash line among them. Windows PowerShell shows a native command's standard error as an error record when the output is redirected with 2>&1. Neither is a failure of the command.

Check. The line begins npm notice. The command's exit status is 0. The deploy line still printed its steps, from its zip: line to the deploy's outcome, and the hash line still printed its sha256: line.

Remedy. None is needed. Read the command's own lines and its exit status, and ignore the notice.

A line of the command says it needs Node.js 24 or later

Cause. The turnzero-cloud command runs on Node.js 24 or later. Under an older release, it checks the version first, so it reads nothing and starts nothing.

Check. The line printed one line, whose first sentence holds the words "Node.js 24 or later" and names the version the command found. The command's exit status is 3. node --version prints a version below v24.

Remedy. Install Node.js 24 or later, as What your computer needs describes. Then run the line again. For a line a deploy call returned, call deploy from your tool again and run the new line instead. The old line's one-time code was never used, and the new call ends it.

Your tool refuses a background process or a file deletion

Cause. Your coding tool refused the command under its own command policy on your machine, such as a sandbox that blocks Start-Process or Remove-Item. Turn Zero Cloud sets no policy on your machine and cannot list another product's.

Check. The refusal names the tool's policy or its sandbox, and no refusal name of the platform.

Remedy. Before the first deploy, run the application on your machine and request its health path. That check needs no server left running in the background. The script below starts src/main.mjs as a child process with PORT set. It requests /health until it answers 200 or 30 tries pass, prints each status, and stops the child. Change the entry and the path to your own.

Save the script as check_local.mjs in the application's folder, and run node --env-file=.env check_local.mjs as one command. It exits 0 only when its own child answered 200. Where the child stops early, for example because another process holds the port, the check fails. The script stops the child on every way out, and gives each attempt two seconds. No test checks this sample.

// check_local.mjs: start the service, check its health path, then stop it.
import { spawn } from 'node:child_process';

const port = '8090';
const child = spawn(process.execPath, ['src/main.mjs'], { env: { ...process.env, PORT: port }, stdio: 'inherit' });
let exited = false;
child.on('exit', () => { exited = true; });
const stop = () => { if (!exited) child.kill(); };
process.on('exit', stop);
for (const signal of ['SIGINT', 'SIGTERM']) process.on(signal, () => { stop(); process.exit(1); });
let healthy = false;
for (let attempt = 1; attempt <= 30 && !healthy && !exited; attempt += 1) {
  await new Promise((resolve) => setTimeout(resolve, 1000));
  if (exited) break;
  try {
    const response = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(2000) });
    console.log(`attempt ${attempt}: ${response.status}`);
    healthy = response.status === 200;
  } catch {
    console.log(`attempt ${attempt}: no answer yet`);
  }
}
if (exited) console.log('the service stopped before the check ended');
stop();
process.exitCode = healthy && !exited ? 0 : 1;

Three steps on these pages use Remove-Item, so a tool that refuses it refuses them too. Two clear a shell variable before a local run: the reset in Add a database, and the remedy in Secrets. In a Unix-style shell, use the env -u form both pages give. In PowerShell, set each name to nothing in the same invocation instead: $env:APP_DATABASE_URL = $null; node --env-file=.env …. For the second page, also set $env:TURNZERO_CLOUD_TOKEN = $null.

The third is the PowerShell form of the unattended step in Store a secret. It writes a temporary value file, stores it, and then removes it with Remove-Item, in one line. Where your tool refuses the line before it runs, nothing ran and no file was written. Your tool then hands you the step to run. Where it refuses only the Remove-Item at the end, the value file stays in the temporary folder, holding the secret. Your tool never reads that file. It tells you the path, and you delete the file yourself.

No step on these pages deletes .env. The provision line replaces its own settings in an existing file and keeps every other line. Leave a refused command refused rather than reaching it another way: where your tool refused to delete a file, the file stays until you delete it.

Invoke-WebRequest fails because the Internet Explorer engine is not available

Cause. In Windows PowerShell 5.1, Invoke-WebRequest parses each response with the Internet Explorer engine unless the command passes -UseBasicParsing. Where that engine is missing or was never set up, the command fails after the request.

Check. The error says that the response content cannot be parsed because the Internet Explorer engine is not available. The command has no -UseBasicParsing switch.

Remedy. Add -UseBasicParsing to the command. The commands.powershell line that mint_upload_grant returns already includes it, and a deploy through the turnzero-cloud command runs no Invoke-WebRequest. To see the body of an error response, run curl.exe -i instead, as Windows PowerShell describes.

A JSON body sent with curl.exe arrives without its quotes

Cause. Windows PowerShell 5.1 passes an argument to a program such as curl.exe without escaping the double quotes inside it. So --data '{"title":"first"}' reaches curl as {title:first}, which is not JSON.

Check. The command ran in Windows PowerShell 5.1 with the body written inline. Your application refuses the body as malformed, as the service in Build a database-backed service answers 400 invalid_note, and the same command succeeds in bash.

Remedy. Write the body to a file without a byte-order mark, and send the file with curl.exe. No test checks this sample.

[System.IO.File]::WriteAllText("$PWD\body.json", '{"title":"first"}')
curl.exe -i -H 'Content-Type: application/json' --data-binary '@body.json' 'https://<label>.ai.host/<path>'

Or send the body with Invoke-RestMethod, a PowerShell command that passes it unchanged. No test checks this sample.

Invoke-RestMethod -Method Post -ContentType 'application/json' -Body (@{title='first'} | ConvertTo-Json -Compress) -Uri 'https://<label>.ai.host/<path>'

In bash, the body passes unchanged with the inline form. No test checks this sample.

curl -H 'Content-Type: application/json' --data '{"title":"first"}' 'https://<label>.ai.host/<path>'

Windows PowerShell lists the other changes the shell needs.

A deploy refuses a zip built on Windows because an entry contains a backslash

Cause. Windows PowerShell 5.1's Compress-Archive writes \ between the segments of each entry's name, as in migrations\0001_guestbook_messages.sql. A zip allows only / there, so the deploy refuses the zip before it adds a version, and counts no deploy.

Check. The deploy response is 400 artifact_layout_invalid. Its detail gives the entry, says it contains a backslash, and gives a tar.exe command.

Remedy. Build the zip with the tar.exe command Build and upload the artifact gives, run in Windows PowerShell from the folder that contains app/, and upload and deploy it as that step describes. Or leave the zip to the turnzero-cloud command, which builds one from the folder with / between segments: call deploy from your tool and run the line its response returns.