Skip to content

Troubleshooting

Ordered by when you hit it. Every entry leads with the symptom as you will experience it, because that is what you will be searching for.

The entries worth reading before you need them are the first three: each fails silently, producing a wrong result with no error anywhere.

A typed-data query returns nothing, and nothing errors

Section titled “A typed-data query returns nothing, and nothing errors”

You wrote a filter that looks obviously correct, the call succeeds, and the result is an empty array — with the rows plainly there.

// Silently matches zero rows.
const recent = await data.notes.findMany({
where: { createdAt: { gte: dayAgo } },
});

Cause. A predicate has to be built, not described. An object with no operator key is not recognized as a predicate, so it is coerced for the comparison and the query becomes "createdAt" = '[object Object]'. That is a valid query against a value nothing equals, so there is nothing to report — you get zero rows and a success. There is no ctx.api.data.find.

Fix. Query the collection with findMany and the query builder for every comparison:

import { q } from '@wamp/extension-sdk';
const recent = await data.notes.findMany({
where: { createdAt: q.gte(dayAgo) },
});

If a query is returning fewer rows than you expect, check every where clause for a bare object before you check anything else. See Typed data.

ctx.api.db was removed. The surviving raw-SQL paths are the migrations[] array on a typed-data schema and data.raw() on the handle defineSchema returns.

The whole extension fails to activate after you add a tool

Section titled “The whole extension fails to activate after you add a tool”

Not one broken tool — the entire extension faults, and nothing it contributes appears.

Cause. Tool names must match ^[a-zA-Z0-9_-]+$. register throws on anything else, register runs inside activate(), and a throw there faults the extension rather than skipping the offending tool. A dot is the usual culprit, because dotted namespacing looks like the natural convention.

Fix. my_app_do_thing, not my_app.do_thing. See Contributing tools.

Section titled “wamp ext dev cannot create the development link”

Cause. Another live wamp ext dev owner or a real extension directory already occupies <userData>/extensions/dynamic/<extension-id>. Stale and unowned symlinks are reclaimed automatically; the CLI never overwrites a real directory or another live owner’s link. A branded Desktop build may also use a different Electron profile from Wamp.

Fix. Stop the other development process or choose a distinct directory id. For another profile, rerun with its exact --user-data-dir. Do not delete a real extension merely to make the link fit. See The wamp CLI.

Cause. The command reaches WAMP through variables that WAMP sets in its own terminals and agent shells. Run anywhere else, they are missing and the message names the one it looked for. An agent runtime that sandboxes commands with the network off also blocks the loopback connection; for Codex the message says so.

Fix. Run it from a WAMP terminal or agent shell. In a sandboxed runtime, rerun the same command with escalated permissions.

wamp ext install or Install from file refuses a built-in or Marketplace id

Section titled “wamp ext install or Install from file refuses a built-in or Marketplace id”

Cause. A built-in or Marketplace extension already holds the id. For wamp ext install the id is the project directory name. An installed copy under that id would never load, so WAMP refuses before writing and leaves the other copy untouched.

Fix. Rename the project directory and install again. Uninstalling the Marketplace copy also frees the id, but deletes that extension’s data.

Cause. A development copy of the same id is loaded: the link of a running wamp ext dev, or a real directory under <profile>/extensions/dynamic/. It takes precedence over the installed copy, which was written anyway.

Fix. Stop wamp ext dev, or remove that directory. The installed copy then loads. See The wamp CLI.

A failed edit makes dev report failed, but the old UI stays visible

Section titled “A failed edit makes dev report failed, but the old UI stays visible”

That is intentional. The SDK builds into a temporary directory and replaces dist/ only after every typecheck, bundle and artifact check succeeds. Fix the reported error and save again; the next ready event replaces the last good bundle.

contributes.tools in the manifest changes nothing

Section titled “contributes.tools in the manifest changes nothing”

The host manifest schema has no such key, and the schema strips unknown keys silently, so declaring tools there is a no-op. Runtime ctx.api.tools.register is the only path. The marketplace does not count the field either, so it cannot earn a listing a “Tool Pack” badge — the tool count on every listing and every installed extension is zero.

A cron schedule is rejected, or never fires

Section titled “A cron schedule is rejected, or never fires”

Cause. The accepted forms are wider than standard cron in one direction and narrower in another. Six fields are accepted (a leading seconds field) as well as five, and a duration shorthand works: 30s, 5m, 1h, 1d. But there is no timezone parameter, and none of L, W, #, ?, or the @daily-style aliases are supported.

Fix. Use five or six numeric fields, or the duration shorthand. See Scheduled work.

Styling looks wrong, and overriding it does not help

Section titled “Styling looks wrong, and overriding it does not help”

Sizes and corners come out different from what the same Tailwind classes give you elsewhere, and /opacity modifiers appear to do nothing on some colors.

Cause. The @wamp/ui Tailwind preset replaces Tailwind’s own type and radius scales, so text-base is 13px and rounded-md is 8px. And /opacity modifiers are only defined for background, foreground, primary, and the semantic colors — on card, muted, or border they emit nothing at all.

Fix. Take sizes from the scale rather than assuming Tailwind’s defaults, and for a translucent surface use one of the tokens that supports it, or an inline style with the token. See Interface kit.

A permission you did not declare seems to work anyway

Section titled “A permission you did not declare seems to work anyway”

Most declarative permissions — ai, filesystem, network, terminal — are disclosure labels rather than runtime gates today; they are not withheld. Other permissions do withhold capabilities: cron, process, identity, notifications, routes, and MCP operations have runtime gates. The local typed store is ungated. ai additionally gates an ACP runtime’s host-funded credential.

Do not read this as permission to skip declarations. They are what a user sees before installing your extension. None of them sandbox Node or UI code; an installed extension is trusted code. See Permissions.