app did not respond on / within 30s
Your build succeeded but the app never answered the health check. In order of likelihood:
- Not listening on
$PORT. The single most common cause — a hardcoded port:
// ✗ hardcoded — fails the health check app.listen(3000); // ✓ reads the assigned port app.listen(process.env.PORT || 3000);
- Crash on boot. A missing env var (
DATABASE_URL, an API key) throws at startup. The build log’s failure message includes the tail of your app’s runtime log — read it; the stack trace is usually right there. /isn’t servable. An API-only app that 404s or 500s on the root path fails the check — a 5xx doesn’t count as alive. Set the project’s health-check path to a route that returns 200, or add a trivial/handler.- Slow start. Loading a large model or dataset at boot can blow the 30-second window — lazy-load heavy work after the server starts listening.
No package.json or index.html found.
Canner looked at the project root and found neither a Node manifest nor a static entry. Usually one of:
- Monorepo / nested app: the app lives in a subfolder. Set Root directory in project settings to that folder.
- Zipped the wrong level: your archive contains a single wrapping folder. Re-zip so
package.json(or your language's equivalent) sits at the archive's root, not one level down. - The repo genuinely lacks them — check that you pushed what you think you pushed.
A lockfile is required to deploy
Builds are reproducible by design, which requires package-lock.json, pnpm-lock.yaml, yarn.lock, or bun.lockb. Run your package manager’s install locally and commit (or include in the upload) the lockfile it writes.
package-lock.json is out of sync with package.json
You edited dependencies without reinstalling. Run npm install locally, then commit the updated lockfile and redeploy.
Could not detect a supported project
The files don’t match any runtime Canner knows: Node, Python, Go, Ruby, PHP, Rust, Java, BoxLang, or static HTML — each detected from its standard manifest at the project root. If it should be detected, check the root-directory setting — detection runs against the configured root.
out of memory
The build exceeded its memory budget (capped per plan — see the limits). Big Next.js builds with type checking are the usual culprit — try typescript.ignoreBuildErrors with a separate CI type check, trim dependencies, or upgrade for more build memory. On Live, App RAM raises build memory too: each GB you assign to a project adds 1 GB to its builds. Once a month, a GitHub build that runs out of memory is retried automatically with more build memory; the deployment page says when that happened. The build log shows how much memory each step used.
Upload fails or the archive won’t extract
A malformed zip (some macOS archive tools produce them) is the usual cause. Use .tar.gz instead, or re-zip with a different tool. Interrupted uploads (Part terminated early) are just a flaky connection — retry.
Still stuck?
Write to hello@canner.ca with your project slug — a human who can see the build logs replies.