> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Ge0frey/nullgraph/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Codes

> Complete reference for all NullGraph custom errors

The NullGraph program defines 6 custom errors to handle validation failures and prevent invalid state transitions. All errors are defined in the `NullGraphError` enum using Anchor's `#[error_code]` macro.

**Location**: `lib.rs:579-593`

## Error Code Enum

```rust theme={null}
#[error_code]
pub enum NullGraphError {
    #[msg("Bounty is not in the expected status")]
    InvalidBountyStatus,
    #[msg("Submission is not in the expected status")]
    InvalidSubmissionStatus,
    #[msg("Matched submission mismatch")]
    SubmissionMismatch,
    #[msg("Bounty deadline has passed")]
    BountyExpired,
    #[msg("Reward amount must be > 0")]
    InvalidRewardAmount,
    #[msg("Fee calculation overflow")]
    FeeOverflow,
}
```

***

## InvalidBountyStatus

<ParamField path="Code" type="6000" />

<ParamField path="Message" type="string">
  "Bounty is not in the expected status"
</ParamField>

### Description

Thrown when an instruction attempts to operate on a bounty that is not in the required status.

### Thrown By

<Expandable title="submit_to_bounty (line 125)">
  **Validation**: `require!(bounty.status == 0, NullGraphError::InvalidBountyStatus)`

  **Condition**: Bounty must have status 0 (Open) to accept submissions.

  **Example**: Attempting to submit an NKA to a bounty that is already Matched (1), Fulfilled (2), or Closed (3).
</Expandable>

<Expandable title="approve_bounty_submission (line 157)">
  **Validation**: `require!(bounty.status == 1, NullGraphError::InvalidBountyStatus)`

  **Condition**: Bounty must have status 1 (Matched) to approve a submission.

  **Example**: Attempting to approve a bounty that is still Open (0) or already Fulfilled (2) or Closed (3).
</Expandable>

<Expandable title="close_bounty (lines 233-236)">
  **Validation**: `require!(bounty.status == 0 || bounty.status == 1, NullGraphError::InvalidBountyStatus)`

  **Condition**: Bounty must have status 0 (Open) or 1 (Matched) to be closed.

  **Example**: Attempting to close a bounty that is already Fulfilled (2) or Closed (3).
</Expandable>

### Status Reference

| Status    | Value | Description           | Valid Operations                            |
| --------- | ----- | --------------------- | ------------------------------------------- |
| Open      | 0     | Accepting submissions | `submit_to_bounty`, `close_bounty`          |
| Matched   | 1     | Submission linked     | `approve_bounty_submission`, `close_bounty` |
| Fulfilled | 2     | Payout complete       | None (terminal state)                       |
| Closed    | 3     | Refunded              | None (terminal state)                       |

### Code Reference

```rust:lib.rs theme={null}
// submit_to_bounty validation (line 125)
let bounty_status = ctx.accounts.bounty.status;
require!(bounty_status == 0, NullGraphError::InvalidBountyStatus); // Must be Open

// approve_bounty_submission validation (line 157)
require!(bounty.status == 1, NullGraphError::InvalidBountyStatus); // Must be Matched

// close_bounty validation (lines 233-236)
require!(
    bounty.status == 0 || bounty.status == 1,
    NullGraphError::InvalidBountyStatus
);
```

***

## InvalidSubmissionStatus

<ParamField path="Code" type="6001" />

<ParamField path="Message" type="string">
  "Submission is not in the expected status"
</ParamField>

### Description

Thrown when attempting to approve a submission that is not in Pending status.

### Thrown By

<Expandable title="approve_bounty_submission (line 164)">
  **Validation**: `require!(submission.status == 0, NullGraphError::InvalidSubmissionStatus)`

  **Condition**: BountySubmission must have status 0 (Pending) to be approved.

  **Example**: Attempting to approve a submission that has already been Approved (1) or Rejected (2).
</Expandable>

### Submission Status Reference

| Status   | Value | Description                   |
| -------- | ----- | ----------------------------- |
| Pending  | 0     | Awaiting creator review       |
| Approved | 1     | Accepted, payout executed     |
| Rejected | 2     | Declined (not currently used) |

### Code Reference

```rust:lib.rs theme={null}
// approve_bounty_submission validation (line 164)
let submission = &mut ctx.accounts.submission;
require!(submission.status == 0, NullGraphError::InvalidSubmissionStatus); // Must be Pending
```

***

## SubmissionMismatch

<ParamField path="Code" type="6002" />

<ParamField path="Message" type="string">
  "Matched submission mismatch"
</ParamField>

### Description

Thrown when the provided BountySubmission account does not match the bounty's recorded `matched_submission` field.

### Thrown By

<Expandable title="approve_bounty_submission (lines 158-161)">
  **Validation**: `require!(bounty.matched_submission == ctx.accounts.submission.key(), NullGraphError::SubmissionMismatch)`

  **Condition**: The `submission` account's public key must exactly match `bounty.matched_submission`.

  **Example**: Passing the wrong BountySubmission PDA when calling `approve_bounty_submission`.
</Expandable>

### Security Note

This check prevents a malicious actor from substituting a different submission during approval. The bounty's `matched_submission` field is set atomically in `submit_to_bounty` and cannot be changed except by approving or closing the bounty.

### Code Reference

```rust:lib.rs theme={null}
// approve_bounty_submission validation (lines 158-161)
require!(
    bounty.matched_submission == ctx.accounts.submission.key(),
    NullGraphError::SubmissionMismatch
);
```

***

## BountyExpired

<ParamField path="Code" type="6003" />

<ParamField path="Message" type="string">
  "Bounty deadline has passed"
</ParamField>

### Description

Reserved for future use. Currently **not thrown** by any instruction.

### Intended Use

This error code exists for potential future enforcement of bounty deadlines. The `NullBounty.deadline` field is stored on-chain but not currently validated by the program.

### Potential Implementation

A future version might add deadline enforcement in `submit_to_bounty`:

```rust theme={null}
let now = Clock::get()?.unix_timestamp;
require!(bounty.deadline >= now, NullGraphError::BountyExpired);
```

<Info>
  The frontend currently filters expired bounties based on the `deadline` field, but the program does not enforce this on-chain.
</Info>

***

## InvalidRewardAmount

<ParamField path="Code" type="6004" />

<ParamField path="Message" type="string">
  "Reward amount must be > 0"
</ParamField>

### Description

Thrown when attempting to create a bounty with a zero or negative reward amount.

### Thrown By

<Expandable title="create_bounty (line 78)">
  **Validation**: `require!(reward_amount > 0, NullGraphError::InvalidRewardAmount)`

  **Condition**: The `reward_amount` parameter must be greater than 0.

  **Example**: Calling `create_bounty` with `reward_amount: 0`.
</Expandable>

### Rationale

A bounty with zero reward provides no incentive and would be pointless. This validation ensures all bounties have economic value.

### Code Reference

```rust:lib.rs theme={null}
// create_bounty validation (line 78)
require!(reward_amount > 0, NullGraphError::InvalidRewardAmount);
```

***

## FeeOverflow

<ParamField path="Code" type="6005" />

<ParamField path="Message" type="string">
  "Fee calculation overflow"
</ParamField>

### Description

Thrown when arithmetic operations during fee calculation result in overflow or underflow.

### Thrown By

<Expandable title="approve_bounty_submission (lines 169-174)">
  **Validation**: All fee/payout calculations use checked arithmetic:

  ```rust theme={null}
  let fee = total
      .checked_mul(fee_bps)
      .ok_or(NullGraphError::FeeOverflow)?
      .checked_div(10_000)
      .ok_or(NullGraphError::FeeOverflow)?;
  let payout = total.checked_sub(fee).ok_or(NullGraphError::FeeOverflow)?;
  ```

  **Condition**: All intermediate calculations must fit within `u64` bounds.

  **Example**: Theoretically possible with extremely large `reward_amount` values exceeding `u64::MAX / fee_basis_points`, but practically impossible with USDC's 6-decimal precision and realistic bounty sizes.
</Expandable>

### Security Note

Using checked arithmetic prevents integer overflow attacks. Even though the inputs make overflow practically impossible, defensive programming ensures the program fails safely rather than silently producing incorrect results.

### Code Reference

```rust:lib.rs theme={null}
// approve_bounty_submission fee calculation (lines 169-174)
let protocol = &ctx.accounts.protocol_state;
let fee_bps = protocol.fee_basis_points as u64;
let total = bounty.reward_amount;
let fee = total
    .checked_mul(fee_bps)
    .ok_or(NullGraphError::FeeOverflow)?
    .checked_div(10_000)
    .ok_or(NullGraphError::FeeOverflow)?;
let payout = total.checked_sub(fee).ok_or(NullGraphError::FeeOverflow)?;
```

***

## Error Handling in Client Code

Anchor errors can be caught and decoded in TypeScript:

```typescript theme={null}
import { AnchorError } from '@coral-xyz/anchor';

try {
  await program.methods.submitToBounty()
    .accounts({ /* ... */ })
    .rpc();
} catch (err) {
  if (err instanceof AnchorError) {
    switch (err.error.errorCode.code) {
      case 'InvalidBountyStatus':
        console.error('This bounty is not accepting submissions');
        break;
      case 'InvalidRewardAmount':
        console.error('Reward must be greater than 0');
        break;
      default:
        console.error('Unknown error:', err.error.errorMessage);
    }
  }
}
```

## Error Code Summary

| Code | Name                      | Message                                  | Currently Used    |
| ---- | ------------------------- | ---------------------------------------- | ----------------- |
| 6000 | `InvalidBountyStatus`     | Bounty is not in the expected status     | Yes (3 locations) |
| 6001 | `InvalidSubmissionStatus` | Submission is not in the expected status | Yes (1 location)  |
| 6002 | `SubmissionMismatch`      | Matched submission mismatch              | Yes (1 location)  |
| 6003 | `BountyExpired`           | Bounty deadline has passed               | No (reserved)     |
| 6004 | `InvalidRewardAmount`     | Reward amount must be > 0                | Yes (1 location)  |
| 6005 | `FeeOverflow`             | Fee calculation overflow                 | Yes (3 locations) |

<Tip>
  All Anchor custom errors automatically include the program ID and instruction context in the transaction error logs, making debugging easier.
</Tip>
