Errors and versioning
Bridge error codes, the API version lifecycle, the deprecation policy, and what happens when a manifest is too old or too new.
Error codes
Every failed bridge call rejects with an Error carrying a code:
| Code | When |
|---|---|
PERMISSION_DENIED | the method or resource is not granted by the widget's manifest (or, for dd.widgets, the target is not user-approved) |
INVALID_PARAMS | params failed host-side validation |
NOT_FOUND | the referenced entity (a key, an item id, a saved network) does not exist; for ids, re-list and retry |
PAYLOAD_TOO_LARGE | a request or response exceeds its documented cap |
TIMEOUT | the operation timed out (host-side, or the SDK's own 15 second client timer) |
RATE_LIMITED | a per-instance rate limit was exceeded; back off |
GONE | the method existed in an older API and was removed. Permanent; the message names the replacement |
INTERNAL | an unexpected host error; details go to the host log |
Handle errors like any other rejected promise, and degrade instead of crashing:
try {
await dd.media.playPause();
} catch (err) {
if (err.code === "RATE_LIMITED") return; // ignore, the user is mashing
dd.log("warn", "playPause failed", err.code);
}Timeouts: the SDK rejects requests client-side after 15 seconds, except the
dd.dialogs.* pickers, which wait on the user (the host guarantees they
settle: a 1 hour backstop plus force-cancel on edit mode, reload, and
removal).
apiVersion: the bridge contract
Your manifest's apiVersion declares which bridge API the widget was
written against. The host runs everything in the range
[minSupported ..= version]; both numbers ride context.api and are
currently both 1.
- Newer than the host: the manifest is quarantined at scan ("requires a newer dashboard") and the widget never loads.
- Older than
minSupported: the widget stays listed, but its instances render a "needs an update" tile instead of mounting, and every bridge call would failGONE.
Deprecation, then removal
API surface is never removed silently:
- A method (or a change in its output) is first deprecated. It keeps
working for at least one release; the SDK warns once per method in your
own console (
[dd] <method> is deprecated: <note>), and the current table ridescontext.api.deprecated. - When
apiVersionbumps, deprecated methods move to removed: calls reject withGONEand a message naming the replacement.
Rules of thumb: watch your console during development, treat any [dd]
deprecation warning as a to-do before the next API bump, and feature-detect
with context.api.version when one widget build should span versions.
minAppVersion: the feature floor
minAppVersion and apiVersion gate different things. apiVersion is the
bridge contract. minAppVersion (a plain x.y.z) says "this widget needs
DeskDash x.y.z or newer":
- An app older than the floor quarantines the manifest with "needs DeskDash x.y.z or newer" instead of a raw parse error.
- The marketplace shows such a listing with a "Needs app update" chip and a disabled Install button.
The store sets it for you. The app keeps a table of the release that last
changed each part of the widget surface: every permission, setting type,
setting key, preset, bundled font and manifest field, the bar kind, and one
entry for everything no permission gates (ungated methods, the dd.*
helpers, the dd-* components, tokens and events). Every new version you
publish is stamped with the newest entry its manifest matches. A value you
write yourself only counts when it is higher, and a published version keeps
the floor it shipped with. Nothing to declare, and nothing to get wrong.
The releases behind the entries, for reference:
| Feature | Since |
|---|---|
the power permission | 0.1.9 |
the folders permission | 0.1.10 |
the games permission | 0.3.2 |
the launchers and feeds permissions, the url setting type and a fractional minSize | 0.3.9 |
kind: "bar", the taskbar permission and the pins / systray presets | 0.3.0 |
dd.bar.strip, bar.strip.changed and <dd-apps sortable> | 0.3.5 |
restartAdvanced for dd.power.run | 0.3.7 |
dd.settings.open, dd.links.open, dd.dialogs.pickDesktopItems and dd.power.run from a bar or its pane | 0.3.7 |
dd.feeds.open | 0.3.11 |
dd.notificationCenter, <dd-notification-bell>, the notificationCenter preset and <dd-bar-button badge> | 0.4.2 |
placeholder and pick on setting fields | 0.1.10 |
the fonts manifest field | 0.2.0 |
Because a permission's entry moves whenever that permission gains a method, an update of your widget can need a newer app than its previous version did even when your code did not change. The stamp shows on the upload's success screen and on your submissions page.