Ship it

Troubleshooting & FAQ

Symptoms, causes and fixes for the problems VibeOS developers actually hit — plus straight answers to the questions that come up most often in review.

Start here

Nearly every issue is diagnosable in the VibeOS IDE: it runs your app against a live SDK, gives you a JavaScript console with command entry, and a Files tab showing the filesystem your app is writing to. Before anything else, open the Console tab and run:

javascript
// Paste this into the IDE console to see what your app can actually do.
const info = await window.vos.app.getInfo();
console.log(info.name, info.sandboxPath, info.permissions);
javascript
// A three-line smoke test for storage.
await window.vos.fs.writeFile(info.sandboxPath, "probe.txt", "hello");
console.log(await window.vos.fs.readFile(info.sandboxPath, "probe.txt"));
await window.vos.fs.deleteFile(info.sandboxPath, "probe.txt");

If those work, your permissions and SDK wiring are fine and the problem is in your app logic. If they do not, the section below matching the error tells you why.

Blank or frozen window

CauseHow to confirmFix
A JavaScript error before your first renderThe IDE console shows a red error on load.Fix the error; render your shell before doing any async work.
Your app waits for data that never arrivesNo error, just an empty window.Render the UI first, then fill it in — and add a timeout to any wait.
An external script or stylesheetConsole shows a Content Security Policy violation.Inline all CSS and JavaScript into the html field.
Only a vos-ready listener, attached too lateNothing runs at all; no errors.Use the check-then-listen pattern below.
html
<!-- These are all blocked inside a .vibe app -->
<script src="https://cdn.example.com/lib.js"></script>
<link rel="stylesheet" href="https://cdn.example.com/style.css">
<img src="https://example.com/photo.jpg">

<!-- Inline everything instead, and load remote images via vos.net.fetch
     as a base64 data URI. -->

window.vos problems

“window.vos is undefined”

javascript
// WRONG — misses the event if the SDK is already ready
window.addEventListener("vos-ready", init);

// RIGHT — handles both orders
if (window.vos) init();
else window.addEventListener("vos-ready", init, { once: true });
  • Reading window.vos at the top of a script that runs before injection gives undefined — always guard.
  • Opening your HTML file directly in a browser tab has no SDK at all. Test in the IDE or inside VibeOS.

“Unknown VOS method”

You called something this host version does not have — most often a newer filesystem method on an older desktop. Feature-detect and degrade:

javascript
if (typeof window.vos.fs.rename === "function") {
  await window.vos.fs.rename(from, to);
} else {
  await copyThenDelete(from, to); // fallback for older hosts
}

“VOS request timed out”

Calls reject after 30 seconds. Split large operations into chunks, and never hold a single call open while waiting on the user.

Filesystem problems

SymptomCauseFix
“app lacks read/write permission”The key is missing from the manifest entirely.Add "read": [] and "write": [] — declaring both is normal.
“path is outside the app's allowed directories”You wrote to a folder the user did not approve.Use app.getInfo().sandboxPath, or request the folder and publish an update.
readFile returns nullThe file does not exist yet — this is not an error.Treat null as first run and seed default state.
Files vanish between sessionsYou wrote to a path built from a value that changes, or used browser storage.Always derive paths from sandboxPath.
The editor keeps reloading while typingYour own writes trigger your own watcher.Set a self-write flag around saves — see vos.fs.
A new folder does not appearThere is no mkdir.Write a placeholder file into it, e.g. .keep.

Network problems

  • Requests fail with a CSP error. You used plain fetch(). Use window.vos.net.fetch().
  • “permission denied” on a URL you declared. The prefix must match exactly, including protocol and host. Declare https://api.example.com/, not api.example.com, and remember the user may have revoked it.
  • “blocked host”. The target is a private or internal address. Public HTTPS endpoints only — you cannot reach a service on the user's machine.
  • “response too large”. Responses are capped at 5 MB; page or filter server-side.
  • Images will not load. Remote img src is blocked. Fetch the bytes and set a base64 data URI.

AI problems

  • Every AI call is rejected. Your manifest is missing "ai": true. Existing installs keep the old grant until the user accepts the update.
  • It works for you, not for a user. Access depends on their sign-in state, plan and remaining credits — handle the rejection with a clear message rather than a spinner that never ends.
  • Replies arrive all at once. There is no streaming; show a typing indicator instead.
  • Replies are not valid JSON. Extract the JSON object from the text and validate before use.
  • err.code is undefined. Expected — branch on err.message. See errors & limits.

Manifest rejected

ProblemFix
Not valid JSONRun it through a JSON validator. Unescaped quotes inside html are the usual culprit.
Unescaped HTML in the html fieldThe whole document is one JSON string: escape every " as \\" and every newline as \\n, or build the app in the IDE which handles this for you.
Unknown permissions keyOnly read, write, ai and network exist. A typo silently removes the capability.
"fs.documents"A removed legacy permission — use the structured permissions object.
Icon does not appeariconImage must be a base64 data URI; external URLs are ignored and the host falls back to iconEmoji.
Wrong type for a permissionread/write/network must be arrays, ai must be a boolean.

FAQ

Can I use React, Vue or a CDN library?

Only if you inline it. There is no external script loading, so bundle everything into the single html string. Most VibeOS apps are plain JavaScript for this reason — it keeps the manifest small and fast to open.

Can I use localStorage or IndexedDB?

They exist, but the sandbox may be reset and nothing syncs with the user's VibeOS storage. Persist real data with vos.fs so it survives, appears in Files, and follows the user.

Can my app read another app's data?

No. The entire home/.apps tree is reserved apart from your own sandbox. Share through a user-visible folder like home/Documents if two apps need the same file.

How do I ship an API key?

You cannot keep one secret — the app is readable and the authorization header is stripped by the proxy. Use APIs that need no key, or let users paste their own and store it in your sandbox.

How do updates reach users?

Submit a new version of the manifest with the same appCenterId; after approval, installed users are offered the upgrade. If the update widens permissions they are asked to approve the new scope.

How big can my app be?

There is no published byte limit, but the manifest is a single JSON document that must load quickly. Keep the icon a small 256px square, avoid embedding large media, and fetch big assets at runtime with vos.net where you can.

Something else is wrong

Include the exact console error and the manifest permissions when you ask for help, and check submission & review for what reviewers look for. If a reviewer requested changes, their notes appear on your app page in the dashboard.

Reproduce it in the IDE first

A bug you can reproduce in the IDE console is usually a bug you can fix in minutes. The Files tab shows exactly what your app wrote, and the console shows exactly what the SDK returned.