Summary
https://run402.com/llms-sdk.txt and the SDK README recommend branching on errors via either:
The SDK exports type guards for "branching with the exported type guards (or by comparing e.kind)" rather than instanceof checks:
isPaymentRequired(e)
isProjectNotFound(e)
isUnauthorized(e)
isRetryableRun402Error(e)
Neither the type guard functions nor the kind property exist in @run402/sdk@1.53.0. Following either documented pattern produces silent wrong-branch behavior or a TypeError.
Repro — type guards are missing
import * as sdk from \"@run402/sdk\";
console.log(typeof sdk.isPaymentRequired); // undefined
console.log(typeof sdk.isProjectNotFound); // undefined
console.log(typeof sdk.isUnauthorized); // undefined
console.log(typeof sdk.isRetryableRun402Error); // undefined
console.log(Object.keys(sdk).sort());
// → [ 'ApiError','Deploy','LocalError','NetworkError','PaymentRequired',
// 'ProjectNotFound','Run402','Run402DeployError','Run402Error',
// 'ScopedRun402','Unauthorized','files','run402' ]
Only the classes are exported. None of the recommended type guard helpers are.
Repro — e.kind is undefined on every error class
import { run402 } from \"@run402/sdk/node\";
const r = run402();
try { await r.projects.info(\"nonexistent_proj_zzz\"); }
catch (e) {
console.log(\"name:\", e.name); // ProjectNotFound
console.log(\"kind:\", e.kind); // undefined
console.log(\"keys:\", Object.getOwnPropertyNames(e));
// → [ 'stack','message','status','body','context','code','category',
// 'retryable','safeToRetry','mutationState','traceId','details',
// 'nextActions','name','projectId' ]
}
The error has code, category, name — but no kind. So the doc's two suggested patterns both fail:
isProjectNotFound(e) → TypeError: isProjectNotFound is not a function
e.kind === \"project_not_found\" → always false
Working pattern is the one the doc says to avoid (e instanceof ProjectNotFound), so anyone following the docs ends up with branching that silently never matches.
Why this matters
The doc explicitly steers consumers away from instanceof — likely because it isn't reliable across realms / dual-loaded SDK copies. But there's no fallback that actually works. This is the kind of quiet bug that sleeps until a user adds a fast-path for "the wallet ran out of credit" and the path silently never fires.
Suggested fix
Pick one of:
-
Export the documented type guards in index.ts:
export const isPaymentRequired = (e) => e?.code === \"PAYMENT_REQUIRED\" || e?.constructor?.name === \"PaymentRequired\";
export const isProjectNotFound = (e) => e?.code === \"PROJECT_NOT_FOUND\" || e?.constructor?.name === \"ProjectNotFound\";
export const isUnauthorized = (e) => e?.constructor?.name === \"Unauthorized\";
export const isRetryableRun402Error = (e) => e?.retryable === true;
-
Add a stable kind discriminator on Run402Error.prototype (\"payment_required\", \"project_not_found\", \"unauthorized\", \"network\", \"local\", \"deploy\", \"api\").
-
Or update the docs to match what's actually exported and recommend e instanceof ProjectNotFound (the only thing that currently works).
I'd vote for #1 + #2 since the doc claims both already exist.
Summary
https://run402.com/llms-sdk.txtand the SDK README recommend branching on errors via either:Neither the type guard functions nor the
kindproperty exist in@run402/sdk@1.53.0. Following either documented pattern produces silent wrong-branch behavior or aTypeError.Repro — type guards are missing
Only the classes are exported. None of the recommended type guard helpers are.
Repro —
e.kindisundefinedon every error classThe error has
code,category,name— but nokind. So the doc's two suggested patterns both fail:isProjectNotFound(e)→TypeError: isProjectNotFound is not a functione.kind === \"project_not_found\"→ alwaysfalseWorking pattern is the one the doc says to avoid (
e instanceof ProjectNotFound), so anyone following the docs ends up with branching that silently never matches.Why this matters
The doc explicitly steers consumers away from
instanceof— likely because it isn't reliable across realms / dual-loaded SDK copies. But there's no fallback that actually works. This is the kind of quiet bug that sleeps until a user adds a fast-path for "the wallet ran out of credit" and the path silently never fires.Suggested fix
Pick one of:
Export the documented type guards in
index.ts:Add a stable
kinddiscriminator onRun402Error.prototype(\"payment_required\",\"project_not_found\",\"unauthorized\",\"network\",\"local\",\"deploy\",\"api\").Or update the docs to match what's actually exported and recommend
e instanceof ProjectNotFound(the only thing that currently works).I'd vote for #1 + #2 since the doc claims both already exist.