When something goes wrong
Every refusal says what happened and what to do about it. This page is for when that is not enough, and for the handful of things that surprise people.
spry: command not found
npm install -g spryloom
If it is installed and still not found, npm's global folder is not on your
PATH. npm prefix -g says where it put the command; add that folder's bin
to your PATH, or use npx spryloom instead.
If spry runs and prints nothing at all, you have a version from before this
was fixed. Install it again.
My agent does not know about Spryloom
spry skill in the project
claude mcp add spryloom -- spry mcp once
The first teaches the agent to write apps that publish; the second gives it the tools to publish them. Both are per-project for the skill and one-off for the server.
If the agent says the tools are there but every call fails, the server started
without a session. spry login, then restart the agent.
The publish failed
Nothing was deployed, and your previous version is still serving. A publish that fails changes nothing: the new version is not started until it is built, and the old one is not retired until the new one is answering.
"Build failed: cannot find 'pg'."
Something is imported and not in package.json.
npm install pg
spry publish .
"Build failed at step: …"
Your build command failed, and the last of its output is shown above the message. It is your app's output, not Spryloom's. Fix the cause and publish again.
"The app built, but it isn't accepting requests."
The app started and never answered on the port it was given. Almost always this:
server.listen(process.env.PORT || 3000, '0.0.0.0');
Not a fixed number, and not 127.0.0.1 — an app bound to loopback cannot be
reached from outside itself.
"This app asks for a database, and this deployment has none to give it."
The manifest declares postgres: true and there is nowhere to create one. The
publish is refused rather than reported as done, because an app that believes it
has a database writes to nothing and finds out later.
"spryloom.yaml is missing, and this app needs a one-sentence description."
Give it one, and Spryloom writes the rest:
spry publish . --description "Tracks expenses that need a second look."
"This folder has no package.json and no index.html, so Spryloom cannot tell what to run."
Publish from the app's own folder, not the root of a repository holding several projects.
A different message — "declares no frontend and no backend, so there is nothing
to run" — is your manifest, not your folder: runtime.frontend and
runtime.backend cannot both be none.
The app is not running
spry apps
If it says STOPPED, it is stopped. That is asked of the platform, not
remembered, so it means what it says.
spry logs expense-notes what it printed before it stopped
spry restart expense-notes start it again
Do not publish again to recover from a crash. The code has not changed, and rebuilding risks a different result from a dependency that moved since. Restart starts the version already there.
If it stops again immediately, the logs will say why. Common: it ran out of memory, usually a query loading a whole table at once.
A coworker cannot get in
They see a sign-in page and never get an email. They cannot use the app.
Spryloom does not send a link to somebody who would be turned away at the door,
and the page says the same thing either way so that it cannot be used to find out
who works somewhere. Check access in the manifest, and spry invite them.
They get in and see "You don't have access to this app." They signed in, and they are not on the list. The page tells them who to ask.
They say the link did not work. Links last fifteen minutes and work once. Ask them to request another.
Something is wrong with my data
The app cannot connect to its database. Check that the manifest says
postgres: true and that you published after adding it. DATABASE_URL is given
to the app when it starts, so a manifest change needs a publish.
A secret is not reaching the app. Secrets reach it when it is published. Set it, then publish again.
The app cannot start without a secret, and the first publish failed. An app cannot be given a secret before it exists. Publish, set the secret, publish again.
I have lost the only copy of a key. Spryloom cannot give it back. There is no command, page, or API that returns a secret's value, deliberately. Get another from wherever it came from and set it again.
I need to undo something
spry rollback expense-notes back to the previous version
spry rollback expense-notes --to 3 back to a particular one
Your data is untouched either way. Rolling back changes which code is running, nothing else — so if the problem was a migration your app ran, rolling back the code does not undo it.
Somebody has left, or a laptop is lost
spry logout --all
Signs out every machine you are on, this one included, by revoking every token you hold. Sign in again afterwards.
For somebody else: take them out of access.admins or the invited list and
publish again.
What is not built yet
Named here rather than left for you to find:
- Google sign-in. Email links only.
signin: [google]is accepted and does nothing. - File uploads, scheduled jobs, and an allow-list for outbound requests. All Release 2. Declaring egress is refused rather than ignored.
- Python. Node today.
- A backup command. The mechanism is exercised, but a restore is an operator doing it for you.
- Archiving an app yourself.
spry appsshows an app asARCHIVED, and putting one in that state is an operator doing it for you. - Changing a role without publishing. Roles come from the manifest; edit
access.adminsand publish again.
Still stuck
spry check shows what Spryloom sees in your folder and whether it could publish
it, without changing anything. It is usually faster than reading a build log.
If a failure message did not tell you what to do, that is a bug in the message and worth saying so. The wording is part of the product.