FAQ & troubleshooting
For everyone
Is a community card safe?
It is sealed in its own box, and can only do what you granted — the app checks every request. But the permissions themselves can be strong: a card allowed to prompt agents or run commands can do anything those agents and terminals can. Install cards from people you trust, and read the dialog. See Installing community cards.
A card asks for my API key inside the card. Should I type it?
No. NeuroSquad never asks for keys inside a card. A well-made card asks for keys in its Settings… form (the app’s own form), where they are stored encrypted and never shown to the card. Anything typed into the card body goes to the card.
Why does a card say “Paused to save memory”?
Cards you have not looked at for a while are suspended so a big canvas stays fast. Look at it — it picks up where it left off.
The card says “Not responding”.
Its code has been busy for more than 15 seconds. Press Reload. If it keeps happening, turn the card off in Settings → Custom cards and tell its author. Nothing else on the canvas is affected.
Why can’t I use a custom card on my phone?
Card code runs only on the computer; the phone shows its header and summary. See On the phone.
Installing says GitHub is limiting requests.
GitHub limits anonymous downloads. Add a GitHub token in Settings → Custom cards — it also lets you install from private repositories.
For authors
connect() fails with UNAVAILABLE.
- Opened outside the app (a browser tab): expected. Use the mock host for previews, as the templates do.
- Inside the app: the SDK must be imported by your entry script, so it is listening before the
page finishes loading. A lazy
import()of the SDK can miss the app’s handshake.
My script does not run. The console says it violates the content security policy.
Cards cannot run inline scripts or onclick="…" attributes, and cannot load scripts, styles,
fonts or images from the internet. Move code into .js files, bundle your dependencies, ship fonts
in the package. npx @neurosquad/card-sdk validate points at the offending lines in your entry page.
See Sandbox rules.
It works with dev but, installed from GitHub, the page is blank or files are missing.
The installed card is exactly what your repository has at that commit. Usually the build output is
not committed (dist/ in .gitignore), or assets are referenced with absolute paths (/assets/…)
instead of relative ones (./assets/…; Vite: base: './'). Run pack --dry-run to see what
users get.
validate says a file “exists but would not be in the package (ignored by git?)”.
The file list is what git would put in a GitHub archive: tracked files plus untracked files that are not ignored. Commit the file, or un-ignore it. This also happens when the card folder sits inside another repository’s ignored folder — move it, or give it its own repository.
PERMISSION_DENIED
The manifest does not declare the permission, the user revoked it, or it is optional and not yet
granted. error.permission names it. Declare it, or ask with card.permissions.request() while the
card is visible. For a linked folder, changing the manifest’s permissions asks you again.
NOT_CONNECTED
The agent, terminal or card you are talking to is not connected to your card by an arrow. Ask the
user to draw one — card.ports.peers and agent.connected tell you what is connected.
emit returns 0.
No downstream peer has a compatible input. Check the arrow’s direction (from your card to the peer),
the types (see Conversion), and, for built-in cards, that you have
cards.connected.
NOT_VISIBLE
Dialogs, links, camera focus, permission requests, the settings form and prompts to agents in
dangerous mode need the card on screen. Call them from a user action, or wait for
lifecycle.visibility to be visible.
RATE_LIMITED
Wait error.retryAfterMs. Per-method limits: attention every 10 s, toasts every 2 s, resize every
500 ms, clipboard every second, prompts 6/min, commands 30/min, network 120/min, port outputs 20/s.
See Limits.
HOST_NOT_ALLOWED
The URL’s host is not in your network hosts (a subdomain does not match an exact host — use
*.example.com), a redirect led somewhere else, or the host resolves to a private address. For
localhost, declare network.local.
My tool never shows up in the agent.
- Only agents connected to the card by an arrow see its tools, and only agents with MCP (Claude Code, Codex, Qwen Code).
- The agent may need a new turn to notice a changed tool list.
- Check the name: agents see
<card name with _>_<tool>, e.g.test_radar_run_tests. card.tools.setEnabled(name, false)hides it for every copy of the card.
Where do I see my card’s errors?
Run npx @neurosquad/card-sdk dev: it streams card.log.*, uncaught errors and rejected promises.
The app keeps the last 256 KB of each package’s log too.
Can my card keep running in the background?
Declare the background permission. Without it, a card whose workspace is hidden for a minute is
suspended: save in card.lifecycle.onSuspend, restore on launch === 'resumed'.
Can I use localStorage, IndexedDB, cookies, WebSockets, window.open?
No — the sandbox has no origin for storage, and no pop-ups. Use card.storage, card.net.fetch
(streaming responses cover server-sent events; WebSockets are not supported in version 1) and
card.openLink.
Can a card read the clipboard, use the camera or the microphone, or pick a file?
Not in version 1. A card can write text to the clipboard (clipboard.write) and work with files in
the workspace folder (fs.read, fs.write).
Is there a gallery of cards?
Not yet — cards are shared by their GitHub address.
My form reloads nothing and posts nothing.
That is by design: submit events fire, but a card page never navigates or posts a form. Handle the
data in your submit handler (call event.preventDefault()). See
Sandbox rules.
My card keeps pulsing after a reload.
Attention set by an earlier run of your page survives reloads and updates. Check
card.context.chrome?.attention on start and clear it with card.attention('none') once the reason
is gone.
dist/ is missing from the package although I built it.
A .gitignore of a parent repository may ignore dist. Add !dist/ to your card’s .gitignore (the
React template does), then check with pack --dry-run.
My copy button does nothing.
Pages cannot write the clipboard through copy events or execCommand. Declare clipboard.write
(optional is fine) and call card.copyText(text).
new Worker('worker.js') fails.
Only blob workers work in a card: fetch the script, make a Blob, and start the worker from
URL.createObjectURL(blob).
My card’s install is refused: “only official cards may call themselves…”.
Cards not published from the official organization may not use “NeuroSquad”, “official” or “verified” in their name or author. Rename it.
A write is refused with FS_DENIED although I have fs.write.
The path is protected (.git, agent settings, CI workflows,
package-manager settings), or the workspace is the home folder or a drive root, where cards get no
file access.