grepticon/
SDK Reference

Error handling

The SDK's dual error model — management calls throw GrepticonError, read tools return a { text, status } envelope — plus 429 retries.

The SDK has two error models, and which one applies depends on the call:

  • Management calls — everything on client.workspaces, client.files, client.tokens, and client.auditthrow GrepticonError on any non-2xx response. Wrap them in try / catch.
  • Read toolsclient.session(ws).ls / .find / .cat / .grep (and the AI-SDK adapter that wraps them) — return a { text, status } envelope and do not throw on not_found / bad_request. The text is steering guidance the agent reads and acts on, so a missing file is a normal result, not an exception.

This split is deliberate: an agent looping over tools should never crash on a typo'd path — it should read the steering text and try again — while your management automation wants a hard failure it can catch.

Management calls: GrepticonError

Any non-2xx from a management call throws a GrepticonError:

class GrepticonError extends Error {
  readonly status: number; // the HTTP status
  message: string; // the server's actionable sentence
}

status is the HTTP status code and message is the server's relayable sentence (for example, the free-plan workspace-quota message, or "Access tokens are read-only…"). Catch it to branch on status:

import { GrepticonError, GrepticonClient } from '@grepticon/sdk';

const client = new GrepticonClient({
  apiKey: process.env.GREPTICON_API_KEY ?? '',
});

try {
  await client.workspaces.create('handbook');
} catch (err) {
  if (err instanceof GrepticonError) {
    console.error(`Grepticon API error ${err.status}: ${err.message}`);
  } else {
    throw err;
  }
}

Read tools: the { text, status } envelope

Session reads resolve to a ToolEnvelope — never a throw for a tool-level miss:

interface ToolEnvelope {
  text: string;
  status: 'ok' | 'not_found' | 'bad_request';
}
statusMeaning
'ok'The read succeeded; text is the result.
'not_found'Path or match didn't exist (or isn't visible to the token).
'bad_request'The tool arguments were invalid.

text always holds a message worth surfacing to the model — for not_found / bad_request it's the steering sentence telling the agent what to try next. The AI-SDK adapter forwards text straight to the model and ignores status; when you call a session directly you can branch on status yourself.

const session = client.session('handbook');
const result = await session.cat({ path: 'guides/onboarding.md' });
if (result.status === 'ok') {
  console.log(result.text);
} else {
  console.warn(`read ${result.status}: ${result.text}`);
}

Only tool-level 404 (not_found) and 400 (bad_request) become envelopes. Auth failures (401 / 403), rate limits (429 after retries), and server errors (5xx) on a read still throw GrepticonError — a bad key or an outage is not something an agent should paper over with a retry.

waitForReady throws only on timeout

files.waitForReady is the exception to the management-throw rule: it does not throw when a file fails to ingest. A file that ends in status: 'error' is a settled, resolved result — waitForReady returns it. It throws (a plain Error, not a GrepticonError) only when it times out before every targeted path settles. So always inspect the returned entries:

const [file] = await client.files.waitForReady('handbook', {
  paths: ['guides/onboarding.md'],
});
if (file?.status === 'error') {
  throw new Error(`Ingestion failed: ${file.errorDetail ?? 'unknown error'}`);
}

Rate limits & automatic 429 retries

Reads are rate-limited per credential and per account. A throttled request returns 429 Too Many Requests with a Retry-After header. The client handles this for you:

  • By default it retries a 429 twice, honoring Retry-After (bounded to a 1–10 second wait) before surfacing the error.
  • Only 429 is retried. Other 4xx and all 5xx responses are not retried — they throw (management) or return their envelope (reads) immediately.

Tune the budget — or opt out entirely — with the retry option:

new GrepticonClient({ apiKey, retry: { retries: 5 } }); // retry up to 5 times
new GrepticonClient({ apiKey, retry: false }); // never retry; surface the 429

RetryOption is false | { retries?: number }. When retries are exhausted, a management call throws GrepticonError with status: 429, and a read throws the same (429 is not one of the envelope statuses).

Where to go next

  • SDK reference — the full client surface these errors come from.
  • AI-SDK adapter — how the envelope reaches the model.
  • Limits — the rate-limit windows behind the 429s.

On this page