or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

agent-definitions.mdagents.mdclient.mdconfiguration-options.mdcontent-blocks.mdcore-query-interface.mdcustom-tools.mderror-handling.mderrors.mdhook-system.mdhooks.mdindex.mdmcp-config.mdmcp-server-configuration.mdmessages-and-content.mdmessages.mdoptions.mdpermission-control.mdpermissions.mdquery.mdtransport.md
COMPLETION_SUMMARY.md

errors.mddocs/

0

# Error Types

1

2

The Claude Agent SDK defines a hierarchy of exception types for different error conditions. All SDK errors inherit from ClaudeSDKError, making it easy to catch all SDK-related exceptions.

3

4

## Capabilities

5

6

### ClaudeSDKError

7

8

Base exception for all Claude SDK errors.

9

10

```python { .api }

11

class ClaudeSDKError(Exception):

12

"""

13

Base exception for all Claude SDK errors.

14

15

All SDK-specific exceptions inherit from this class, allowing you

16

to catch all SDK errors with a single except clause.

17

18

Example:

19

try:

20

async for msg in query(prompt="Hello"):

21

print(msg)

22

except ClaudeSDKError as e:

23

print(f"SDK error: {e}")

24

"""

25

```

26

27

### CLIConnectionError

28

29

Raised when unable to connect to Claude Code.

30

31

```python { .api }

32

class CLIConnectionError(ClaudeSDKError):

33

"""

34

Raised when unable to connect to Claude Code.

35

36

This error occurs when the SDK cannot establish a connection to the

37

Claude Code CLI process. This can happen if:

38

- The CLI is not installed

39

- The CLI path is incorrect

40

- Network issues (for remote transports)

41

- Permission issues

42

43

Inherits from: ClaudeSDKError

44

"""

45

```

46

47

### CLINotFoundError

48

49

Raised when Claude Code CLI is not found or not installed.

50

51

```python { .api }

52

class CLINotFoundError(CLIConnectionError):

53

"""

54

Raised when Claude Code is not found or not installed.

55

56

This specific connection error occurs when the SDK cannot locate the

57

Claude Code CLI executable. This typically means Claude Code is not

58

installed or not in the system PATH.

59

60

Inherits from: CLIConnectionError

61

62

Constructor:

63

__init__(

64

message: str = "Claude Code not found",

65

cli_path: str | None = None

66

)

67

68

Attributes:

69

cli_path: The path where the CLI was expected (if known)

70

"""

71

72

def __init__(

73

self,

74

message: str = "Claude Code not found",

75

cli_path: str | None = None

76

):

77

"""

78

Initialize CLINotFoundError.

79

80

Args:

81

message: Error message. Defaults to "Claude Code not found"

82

cli_path: Optional path where CLI was expected. If provided,

83

will be appended to the error message.

84

85

Example:

86

CLINotFoundError("Custom message", "/usr/local/bin/claude")

87

"""

88

```

89

90

### ProcessError

91

92

Raised when the CLI process fails.

93

94

```python { .api }

95

class ProcessError(ClaudeSDKError):

96

"""

97

Raised when the CLI process fails.

98

99

This error occurs when the Claude Code CLI process exits with an error

100

or fails during execution. Contains details about the failure including

101

exit code and stderr output.

102

103

Inherits from: ClaudeSDKError

104

105

Constructor:

106

__init__(

107

message: str,

108

exit_code: int | None = None,

109

stderr: str | None = None

110

)

111

112

Attributes:

113

exit_code: Process exit code (if available)

114

stderr: Standard error output from the process (if available)

115

"""

116

117

def __init__(

118

self,

119

message: str,

120

exit_code: int | None = None,

121

stderr: str | None = None

122

):

123

"""

124

Initialize ProcessError.

125

126

Args:

127

message: Error description

128

exit_code: Optional process exit code

129

stderr: Optional stderr output from process

130

131

Example:

132

ProcessError(

133

"Process failed",

134

exit_code=1,

135

stderr="Error: Invalid argument"

136

)

137

138

Notes:

139

- Exit code and stderr are automatically appended to the message

140

- The formatted message includes exit code if available

141

- Stderr output is included in formatted message if available

142

"""

143

144

exit_code: int | None

145

"""Process exit code.

146

147

The exit code returned by the CLI process. None if process didn't

148

exit normally or exit code is unknown.

149

150

Common values:

151

- 0: Success (but wouldn't raise ProcessError)

152

- 1: General error

153

- 2: Misuse of shell command

154

- 126: Command cannot execute

155

- 127: Command not found

156

- 130: Terminated by Ctrl+C

157

"""

158

159

stderr: str | None

160

"""Standard error output.

161

162

The stderr output from the CLI process. None if no stderr was captured

163

or process didn't produce stderr output.

164

165

This typically contains error messages, warnings, and diagnostic

166

information from the CLI.

167

"""

168

```

169

170

### CLIJSONDecodeError

171

172

Raised when unable to decode JSON from CLI output.

173

174

```python { .api }

175

class CLIJSONDecodeError(ClaudeSDKError):

176

"""

177

Raised when unable to decode JSON from CLI output.

178

179

This error occurs when the CLI produces output that cannot be parsed

180

as JSON. This usually indicates a protocol error or corrupted output.

181

182

Inherits from: ClaudeSDKError

183

184

Constructor:

185

__init__(line: str, original_error: Exception)

186

187

Attributes:

188

line: The line that failed to parse

189

original_error: The underlying JSON decode exception

190

"""

191

192

def __init__(self, line: str, original_error: Exception):

193

"""

194

Initialize CLIJSONDecodeError.

195

196

Args:

197

line: The line that failed to parse (truncated to 100 chars in message)

198

original_error: The original exception from JSON parsing

199

200

Example:

201

CLIJSONDecodeError(

202

"{invalid json",

203

json.JSONDecodeError("msg", "doc", 0)

204

)

205

206

Notes:

207

- Error message shows first 100 characters of problematic line

208

- Original error is preserved for debugging

209

"""

210

211

line: str

212

"""Line that failed to parse.

213

214

The complete line from CLI output that could not be decoded as JSON.

215

This is the raw string that caused the parsing error.

216

"""

217

218

original_error: Exception

219

"""Original exception.

220

221

The underlying exception that occurred during JSON parsing. Usually

222

a json.JSONDecodeError with details about what went wrong.

223

224

Useful for debugging the specific parsing issue.

225

"""

226

```

227

228

### MessageParseError

229

230

Raised when unable to parse a message from CLI output.

231

232

```python { .api }

233

class MessageParseError(ClaudeSDKError):

234

"""

235

Raised when unable to parse a message from CLI output.

236

237

This error occurs when the CLI output is valid JSON but doesn't match

238

the expected message structure. This indicates a protocol mismatch or

239

unexpected message format.

240

241

Inherits from: ClaudeSDKError

242

243

Constructor:

244

__init__(message: str, data: dict[str, Any] | None = None)

245

246

Attributes:

247

data: The message data that failed to parse (if available)

248

"""

249

250

def __init__(self, message: str, data: dict[str, Any] | None = None):

251

"""

252

Initialize MessageParseError.

253

254

Args:

255

message: Error description

256

data: Optional message data that failed to parse

257

258

Example:

259

MessageParseError(

260

"Unknown message type",

261

{"type": "unknown", "data": {...}}

262

)

263

264

Notes:

265

- Message describes what went wrong during parsing

266

- Data contains the raw message dict for debugging

267

"""

268

269

data: dict[str, Any] | None

270

"""Message data.

271

272

The parsed JSON data that couldn't be converted to a proper message

273

object. None if data is not available.

274

275

This is the dictionary that was successfully parsed as JSON but

276

doesn't match expected message schemas.

277

"""

278

```

279

280

## Usage Examples

281

282

### Basic Error Handling

283

284

```python

285

from claude_agent_sdk import query, ClaudeSDKError

286

287

try:

288

async for msg in query(prompt="Hello Claude"):

289

print(msg)

290

except ClaudeSDKError as e:

291

print(f"SDK error occurred: {e}")

292

```

293

294

### Handling Specific Errors

295

296

```python

297

from claude_agent_sdk import (

298

query, CLINotFoundError, CLIConnectionError,

299

ProcessError, ClaudeSDKError

300

)

301

302

try:

303

async for msg in query(prompt="Hello"):

304

print(msg)

305

306

except CLINotFoundError as e:

307

print("Claude Code is not installed or not in PATH")

308

print("Please install from: https://claude.com/code")

309

310

except CLIConnectionError as e:

311

print(f"Cannot connect to Claude Code: {e}")

312

print("Make sure Claude Code is running")

313

314

except ProcessError as e:

315

print(f"CLI process failed: {e}")

316

if e.exit_code:

317

print(f"Exit code: {e.exit_code}")

318

if e.stderr:

319

print(f"Error output: {e.stderr}")

320

321

except ClaudeSDKError as e:

322

print(f"Other SDK error: {e}")

323

```

324

325

### Installation Check

326

327

```python

328

from claude_agent_sdk import query, CLINotFoundError

329

330

async def check_claude_installed():

331

"""Check if Claude Code is installed."""

332

try:

333

async for msg in query(prompt="test"):

334

# If we get here, Claude is installed

335

return True

336

except CLINotFoundError:

337

return False

338

339

if await check_claude_installed():

340

print("Claude Code is installed")

341

else:

342

print("Please install Claude Code")

343

```

344

345

### Detailed Error Information

346

347

```python

348

from claude_agent_sdk import query, ProcessError

349

350

try:

351

async for msg in query(prompt="Hello"):

352

print(msg)

353

354

except ProcessError as e:

355

print("Process Error Details:")

356

print(f" Message: {e}")

357

print(f" Exit Code: {e.exit_code}")

358

print(f" Stderr: {e.stderr}")

359

360

# Check specific exit codes

361

if e.exit_code == 127:

362

print(" Diagnosis: Command not found")

363

elif e.exit_code == 126:

364

print(" Diagnosis: Command cannot execute (permission issue?)")

365

elif e.exit_code == 130:

366

print(" Diagnosis: Process interrupted by user")

367

```

368

369

### Retry Logic

370

371

```python

372

import anyio

373

from claude_agent_sdk import query, CLIConnectionError, ClaudeSDKError

374

375

async def query_with_retry(prompt: str, max_retries: int = 3):

376

"""Query with automatic retry on connection errors."""

377

for attempt in range(max_retries):

378

try:

379

async for msg in query(prompt=prompt):

380

print(msg)

381

return # Success

382

383

except CLIConnectionError as e:

384

if attempt < max_retries - 1:

385

print(f"Connection failed (attempt {attempt + 1}/{max_retries})")

386

print("Retrying in 2 seconds...")

387

await anyio.sleep(2)

388

else:

389

print("Max retries reached")

390

raise

391

392

except ClaudeSDKError:

393

# Don't retry other errors

394

raise

395

396

await query_with_retry("Hello Claude")

397

```

398

399

### JSON Decode Error Handling

400

401

```python

402

from claude_agent_sdk import query, CLIJSONDecodeError

403

404

try:

405

async for msg in query(prompt="Hello"):

406

print(msg)

407

408

except CLIJSONDecodeError as e:

409

print("Failed to parse CLI output")

410

print(f"Problematic line: {e.line[:200]}") # Show first 200 chars

411

print(f"Original error: {e.original_error}")

412

print("This might indicate a CLI version mismatch")

413

```

414

415

### Message Parse Error Handling

416

417

```python

418

from claude_agent_sdk import query, MessageParseError

419

420

try:

421

async for msg in query(prompt="Hello"):

422

print(msg)

423

424

except MessageParseError as e:

425

print("Failed to parse message structure")

426

print(f"Error: {e}")

427

if e.data:

428

print(f"Raw data: {e.data}")

429

print("This might indicate a protocol version mismatch")

430

```

431

432

### Error Logging

433

434

```python

435

import logging

436

from claude_agent_sdk import query, ClaudeSDKError, ProcessError

437

438

logging.basicConfig(level=logging.ERROR)

439

logger = logging.getLogger(__name__)

440

441

try:

442

async for msg in query(prompt="Hello"):

443

print(msg)

444

445

except ProcessError as e:

446

logger.error(

447

"Process error",

448

extra={

449

"exit_code": e.exit_code,

450

"stderr": e.stderr,

451

"message": str(e)

452

}

453

)

454

455

except ClaudeSDKError as e:

456

logger.error(f"SDK error: {e}", exc_info=True)

457

```

458

459

### Error Recovery

460

461

```python

462

from claude_agent_sdk import (

463

query, ClaudeSDKError, CLINotFoundError,

464

ProcessError, ClaudeAgentOptions

465

)

466

467

async def robust_query(prompt: str):

468

"""Query with error recovery strategies."""

469

try:

470

async for msg in query(prompt=prompt):

471

print(msg)

472

473

except CLINotFoundError:

474

print("Installing Claude Code would fix this...")

475

# Could trigger installation process here

476

raise

477

478

except ProcessError as e:

479

if e.exit_code == 1 and e.stderr and "permission" in e.stderr.lower():

480

print("Try running with different permissions")

481

else:

482

print(f"Process failed: {e}")

483

raise

484

485

except ClaudeSDKError as e:

486

print(f"Unexpected error: {e}")

487

raise

488

489

await robust_query("Hello Claude")

490

```

491

492

### User-Friendly Error Messages

493

494

```python

495

from claude_agent_sdk import (

496

query, CLINotFoundError, CLIConnectionError,

497

ProcessError, ClaudeSDKError

498

)

499

500

async def query_with_friendly_errors(prompt: str):

501

"""Query with user-friendly error messages."""

502

try:

503

async for msg in query(prompt=prompt):

504

print(msg)

505

506

except CLINotFoundError:

507

print("\nClaude Code Not Found")

508

print("=" * 50)

509

print("Claude Code needs to be installed to use this SDK.")

510

print("\nInstallation instructions:")

511

print("1. Visit https://claude.com/code")

512

print("2. Download and install Claude Code")

513

print("3. Make sure 'claude' is in your PATH")

514

515

except CLIConnectionError as e:

516

print("\nConnection Error")

517

print("=" * 50)

518

print("Could not connect to Claude Code.")

519

print(f"\nDetails: {e}")

520

print("\nPossible solutions:")

521

print("- Check if Claude Code is running")

522

print("- Try restarting Claude Code")

523

print("- Check your network connection")

524

525

except ProcessError as e:

526

print("\nProcess Error")

527

print("=" * 50)

528

print("Claude Code process encountered an error.")

529

if e.exit_code:

530

print(f"Exit code: {e.exit_code}")

531

if e.stderr:

532

print(f"Error details: {e.stderr}")

533

534

except ClaudeSDKError as e:

535

print("\nUnexpected Error")

536

print("=" * 50)

537

print(f"An unexpected error occurred: {e}")

538

print("Please report this issue if it persists")

539

540

await query_with_friendly_errors("Hello")

541

```

542

543

### Exception Chaining

544

545

```python

546

from claude_agent_sdk import query, ClaudeSDKError

547

548

class ApplicationError(Exception):

549

"""Custom application error."""

550

pass

551

552

try:

553

async for msg in query(prompt="Hello"):

554

print(msg)

555

556

except ClaudeSDKError as e:

557

# Chain SDK error with application error

558

raise ApplicationError("Failed to query Claude") from e

559

```

560

561

### Error Metrics

562

563

```python

564

from collections import defaultdict

565

from claude_agent_sdk import (

566

query, CLINotFoundError, CLIConnectionError,

567

ProcessError, ClaudeSDKError

568

)

569

570

error_counts = defaultdict(int)

571

572

async def query_with_metrics(prompt: str):

573

"""Track error types for monitoring."""

574

try:

575

async for msg in query(prompt=prompt):

576

print(msg)

577

578

except CLINotFoundError as e:

579

error_counts["cli_not_found"] += 1

580

raise

581

582

except CLIConnectionError as e:

583

error_counts["connection_error"] += 1

584

raise

585

586

except ProcessError as e:

587

error_counts["process_error"] += 1

588

raise

589

590

except ClaudeSDKError as e:

591

error_counts["other_sdk_error"] += 1

592

raise

593

594

# Later, check metrics

595

print("Error statistics:")

596

for error_type, count in error_counts.items():

597

print(f" {error_type}: {count}")

598

```

599

600

### Conditional Error Handling

601

602

```python

603

from claude_agent_sdk import query, ProcessError, ClaudeSDKError

604

605

async def handle_errors_conditionally(prompt: str, strict: bool = False):

606

"""Handle errors differently based on mode."""

607

try:

608

async for msg in query(prompt=prompt):

609

print(msg)

610

611

except ProcessError as e:

612

if strict:

613

# In strict mode, fail immediately

614

raise

615

else:

616

# In lenient mode, log and continue

617

print(f"Warning: Process error occurred: {e}")

618

print("Continuing anyway...")

619

620

except ClaudeSDKError as e:

621

if strict:

622

raise

623

else:

624

print(f"Warning: SDK error: {e}")

625

626

# Strict mode

627

await handle_errors_conditionally("Hello", strict=True)

628

629

# Lenient mode

630

await handle_errors_conditionally("Hello", strict=False)

631

```

632

633

### Error Context Manager

634

635

```python

636

from contextlib import asynccontextmanager

637

from claude_agent_sdk import query, ClaudeSDKError

638

639

@asynccontextmanager

640

async def handle_sdk_errors():

641

"""Context manager for SDK error handling."""

642

try:

643

yield

644

except ClaudeSDKError as e:

645

print(f"SDK Error: {e}")

646

# Log to file, send to monitoring, etc.

647

raise

648

649

async def main():

650

async with handle_sdk_errors():

651

async for msg in query(prompt="Hello"):

652

print(msg)

653

654

await main()

655

```

656