Skip to content

Error Types

llmist provides specific error types for different scenarios. Understanding these helps you build robust applications.

These exceptions are used to control agent flow, not indicate errors:

Pauses the agent loop to request user input.

import { Gadget, HumanInputRequiredException, z } from 'llmist';
class AskUser extends Gadget({
description: 'Ask user for input',
schema: z.object({ question: z.string() }),
}) {
execute(params: this['params']): string {
throw new HumanInputRequiredException(params.question);
}
}

Behavior:

  • Agent loop pauses
  • Question is presented to user
  • User response is fed back to the agent
  • Agent continues with the response

Signals that the agent has completed its task.

import { Gadget, TaskCompletionSignal, z } from 'llmist';
class Done extends Gadget({
description: 'Signal task completion',
schema: z.object({ summary: z.string() }),
}) {
execute(params: this['params']): string {
throw new TaskCompletionSignal(params.summary);
}
}

Behavior:

  • Agent loop terminates immediately
  • Summary is returned as the final result
  • No further iterations occur

Signals that a gadget execution was denied (e.g., by approval system).

import { GadgetDenySignal } from 'llmist';
// Thrown internally when gadget approval is denied
throw new GadgetDenySignal('User denied file write operation');

Behavior:

  • Gadget execution is skipped
  • Denial message is sent back to the LLM
  • Agent can try alternative approaches

Base class for all provider-related errors.

import { ProviderError } from 'llmist';
try {
await agent.run();
} catch (error) {
if (error instanceof ProviderError) {
console.log('Provider:', error.provider);
console.log('Message:', error.message);
}
}

Thrown when API rate limits are exceeded.

import { RateLimitError } from 'llmist';
try {
await agent.run();
} catch (error) {
if (error instanceof RateLimitError) {
console.log('Retry after:', error.retryAfter, 'seconds');
}
}

Handling:

  • Use retry configuration
  • Implement exponential backoff
  • Consider using a different model

Thrown when API authentication fails.

import { AuthenticationError } from 'llmist';
try {
await agent.run();
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Check your API key');
}
}

Thrown when a gadget fails during execution.

import { GadgetExecutionError } from 'llmist';
for await (const event of agent.run()) {
if (event.type === 'gadget_error') {
console.log('Gadget:', event.gadgetName);
console.log('Error:', event.error.message);
}
}

Thrown when a gadget exceeds its timeout.

class SlowGadget extends Gadget({
description: 'A slow operation',
schema: z.object({}),
timeoutMs: 5000, // 5 second timeout
}) {
async execute(): Promise<string> {
// If this takes > 5 seconds, GadgetTimeoutError is thrown
await someSlowOperation();
return 'done';
}
}

Thrown when gadget parameters fail Zod validation.

import { GadgetValidationError } from 'llmist';
// If LLM provides invalid parameters:
// { filename: 123, megabytes: "fifty" } // should be string and number
// GadgetValidationError is thrown with validation details

Thrown when the block format parser encounters invalid syntax.

Common causes:

  • Duplicate parameter paths
  • Invalid array indices
  • Malformed markers
for await (const event of agent.run()) {
if (event.type === 'gadget_parse_error') {
console.log('Parse error:', event.parseError);
console.log('Raw text:', event.parametersRaw);
}
}
const agent = LLMist.createAgent()
.withModel('sonnet')
.withRetry({
maxAttempts: 3,
retryOn: ['rate_limit', 'server_error'],
backoff: 'exponential',
});
for await (const event of agent.run()) {
switch (event.type) {
case 'gadget_error':
console.error(`Gadget ${event.gadgetName} failed:`, event.error);
break;
case 'llm_error':
console.error('LLM call failed:', event.error);
break;
}
}
try {
const result = await agent.askAndCollect('Do something');
} catch (error) {
if (error instanceof TaskCompletionSignal) {
// Expected - task completed normally
console.log('Result:', error.message);
} else if (error instanceof HumanInputRequiredException) {
// Need user input
const input = await promptUser(error.message);
// Continue with input...
} else {
// Actual error
throw error;
}
}