Errors
The PromptVaultError class, its typed codes, and recommended recovery patterns.
Every error the SDK throws is an instance of PromptVaultError with a typed code field. This makes it cheap to handle the cases you care about and let everything else bubble.
import { PromptVaultError } from "@promptv/sdk";
try {
await pv.get("does-not-exist");
} catch (err) {
if (err instanceof PromptVaultError && err.code === "not_found") {
return notFoundResponse();
}
throw err;
}Codes
| Code | Thrown when | Recovery |
|---|---|---|
missing_key | The constructor is called without a key (or with an empty string). | Set PROMPTV_KEY and re-instantiate. |
not_found | The prompt slug doesn't exist in the workspace this key reads. | Either fix the slug, or treat as a real "deleted" condition - the cache will not paper over it. |
version_not_found | The label passed to .version() doesn't exist on this prompt. | Call .listVersions() to discover available labels. |
transport_error | Network failure, 5xx, or any unexpected throw inside the transport. | Eligible for stale-on-error fallback (see Caching). If no cached entry exists, the error propagates. |
Error class
class PromptVaultError extends Error {
readonly name: "PromptVaultError";
readonly code: "missing_key" | "not_found" | "version_not_found" | "transport_error";
}How errors interact with the cache
The cache distinguishes authoritative failures from transport failures:
| Outcome | Behaviour |
|---|---|
transport_error (or any non-PromptVaultError throw) with a cached entry present | Stale entry is returned; no error is propagated. |
transport_error with no cached entry | Error propagates as-is. |
not_found / version_not_found | Error always propagates. We don't serve stale data when the API has authoritatively said the prompt is gone. |
This matters when you're tuning your client. By the time an error reaches your try/catch, the SDK has already attempted stale-fallback recovery.
Patterns
Treat missing prompts as bugs
Most production code shouldn't catch not_found; a missing slug is an integration bug, and the right response is a loud failure:
const prompt = await pv.get("support-triage"); // let it throwTreat missing prompts as data
For systems that build prompt slugs at runtime, check explicitly:
async function safeGet(slug: string) {
try {
return await pv.get(slug);
} catch (err) {
if (err instanceof PromptVaultError && err.code === "not_found") return null;
throw err;
}
}Surface transport errors to your monitoring
Wrap the client to count failures:
async function instrumented<T>(label: string, fn: () => Promise<T>): Promise<T> {
try {
return await fn();
} catch (err) {
if (err instanceof PromptVaultError && err.code === "transport_error") {
metrics.increment("promptvault.transport_error", { label });
}
throw err;
}
}The cache will already have absorbed transient failures when a warm entry exists - what reaches your catch is genuine: either there's no cache yet, or cache: false, or it's a non-transport error.