> ## Documentation Index
> Fetch the complete documentation index at: https://memproof.kyberon.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error classes, error codes, and exception handling in Memproof.

# Errors

All Memproof exceptions inherit from `MemproofError`. Every exception carries three attributes:

* `code` -- a machine-readable error code string (e.g., `"POLICY_DENIED"`).
* `message` -- a human-readable description of the error.
* `details` -- an optional dictionary with additional context.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import MemproofError, PolicyDeniedError, NotFoundError
```

***

## Base Exception

### MemproofError

The base class for all Memproof errors. You can catch this to handle any Memproof-specific exception.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class MemproofError(Exception):
    def __init__(self, code: str, message: str, details: dict | None = None):
        self.code = code
        self.message = message
        self.details = details
```

<ParamField path="code" type="str">
  Machine-readable error code. Each subclass sets a fixed code value.
</ParamField>

<ParamField path="message" type="str">
  Human-readable error message.
</ParamField>

<ParamField path="details" type="dict | None">
  Optional dictionary with structured error details (e.g., validation field errors, matched rule IDs).
</ParamField>

#### Example

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
try:
    result = await mp.remember(
        content="sensitive data",
        scope={"tenant_id": "t1", "project_id": "p1", "agent_id": "a1"},
        context={
            "actor_type": "agent", "actor_id": "a1",
            "source": "langgraph", "timestamp": "2026-01-15T10:30:00Z",
        },
    )
except MemproofError as e:
    print(f"[{e.code}] {e.message}")
    if e.details:
        print(e.details)
```

***

## Error Subclasses

### ValidationError

**Code:** `VALIDATION_ERROR`

Raised when input data fails validation -- for example, when a required field is missing, a field value is out of range, or the content string is empty.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class ValidationError(MemproofError):
    def __init__(self, message: str, details: dict | None = None):
        super().__init__("VALIDATION_ERROR", message, details)
```

<ParamField path="message" type="str" required>
  Description of the validation failure.
</ParamField>

<ParamField path="details" type="dict | None" default="None">
  Optional dictionary with field-level error information. For example: `{"field": "content", "error": "must be non-empty"}`.
</ParamField>

**When raised:**

* Content is empty or missing.
* Scope is missing required fields (`tenant_id`, `project_id`, `agent_id`).
* `ttl_seconds` is not a positive integer.
* `limit` is outside the 1--100 range.

#### Example

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import ValidationError

try:
    result = await mp.remember(
        content="",  # empty content triggers validation error
        scope={"tenant_id": "t1", "project_id": "p1", "agent_id": "a1"},
        context={
            "actor_type": "agent", "actor_id": "a1",
            "source": "langgraph", "timestamp": "2026-01-15T10:30:00Z",
        },
    )
except ValidationError as e:
    print(e.message)  # "Content must be non-empty"
```

***

### NotFoundError

**Code:** `NOT_FOUND`

Raised when a requested resource does not exist.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class NotFoundError(MemproofError):
    def __init__(self, message: str = "Not found"):
        super().__init__("NOT_FOUND", message)
```

<ParamField path="message" type="str" default="&#x22;Not found&#x22;">
  Description of what was not found.
</ParamField>

**When raised:**

* `get()` is called with a `memory_id` that does not exist.
* `update()` or `forget()` targets a non-existent memory.
* `get_operation_status()` is called with an unknown `operation_id`.

#### Example

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import NotFoundError

try:
    record = await mp.get("non-existent-id")
except NotFoundError as e:
    print(e.message)  # "Not found"
```

***

### ConflictError

**Code:** `CONFLICT`

Raised when an operation conflicts with the current state -- typically an idempotency conflict or a concurrent modification.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class ConflictError(MemproofError):
    def __init__(self, message: str = "Conflict", details: dict | None = None):
        super().__init__("CONFLICT", message, details)
```

<ParamField path="message" type="str" default="&#x22;Conflict&#x22;">
  Description of the conflict.
</ParamField>

<ParamField path="details" type="dict | None" default="None">
  Optional details about the conflict (e.g., `{"idempotency_key": "mp-abc", "existing_operation_id": "op-xyz"}`).
</ParamField>

**When raised:**

* An `idempotency_key` is reused with different parameters than the original request.
* A concurrent modification is detected by the adapter.

#### Example

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import ConflictError

try:
    result = await mp.remember(
        content="different content",
        scope={"tenant_id": "t1", "project_id": "p1", "agent_id": "a1"},
        context={
            "actor_type": "agent", "actor_id": "a1",
            "source": "langgraph", "timestamp": "2026-01-15T10:30:00Z",
        },
        idempotency_key="already-used-key",
    )
except ConflictError as e:
    print(e.message)
    print(e.details)
```

***

### PolicyDeniedError

**Code:** `POLICY_DENIED`

Raised when the policy engine denies an operation based on the configured rules and risk assessment.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class PolicyDeniedError(MemproofError):
    def __init__(self, message: str = "Operation denied by policy rule.", details: dict | None = None):
        super().__init__("POLICY_DENIED", message, details)
```

<ParamField path="message" type="str" default="&#x22;Operation denied by policy rule.&#x22;">
  Explanation of the denial.
</ParamField>

<ParamField path="details" type="dict | None" default="None">
  May contain `reason_codes`, `matched_rule_ids`, and `risk_assessment` for debugging.
</ParamField>

**When raised:**

* The policy engine evaluates the operation and returns a `deny` action.
* A rule explicitly blocks the operation based on content, scope, risk level, or other criteria.

#### Example

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import PolicyDeniedError

try:
    result = await mp.remember(
        content="store social security number 123-45-6789",
        scope={"tenant_id": "t1", "project_id": "p1", "agent_id": "a1"},
        context={
            "actor_type": "agent", "actor_id": "a1",
            "source": "langgraph", "timestamp": "2026-01-15T10:30:00Z",
        },
    )
except PolicyDeniedError as e:
    print(e.code)     # "POLICY_DENIED"
    print(e.message)  # "Operation denied by policy rule."
    print(e.details)  # {"reason_codes": ["pii_detected"], ...}
```

***

### QuarantinedError

**Code:** `QUARANTINED`

Raised when the policy engine quarantines an operation for offline review. The memory is not persisted until the quarantine is resolved.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class QuarantinedError(MemproofError):
    def __init__(self, message: str = "Operation quarantined.", details: dict | None = None):
        super().__init__("QUARANTINED", message, details)
```

<ParamField path="message" type="str" default="&#x22;Operation quarantined.&#x22;">
  Explanation of the quarantine.
</ParamField>

<ParamField path="details" type="dict | None" default="None">
  May contain the `operation_id` and `reason_codes`.
</ParamField>

**When raised:**

* The policy engine returns a `quarantine` action.
* The risk score or content triggers a quarantine rule in the policy configuration.

#### Example

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import QuarantinedError

try:
    result = await mp.remember(
        content="potentially problematic content",
        scope={"tenant_id": "t1", "project_id": "p1", "agent_id": "a1"},
        context={
            "actor_type": "agent", "actor_id": "a1",
            "source": "langgraph", "timestamp": "2026-01-15T10:30:00Z",
        },
    )
except QuarantinedError as e:
    print(e.code)    # "QUARANTINED"
    print(e.details) # {"operation_id": "op-abc", ...}
```

***

### ApprovalDeniedError

**Code:** `APPROVAL_DENIED`

Raised when a pending operation is explicitly denied by a human reviewer via the `deny()` method.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class ApprovalDeniedError(MemproofError):
    def __init__(self, message: str = "Approval denied.", details: dict | None = None):
        super().__init__("APPROVAL_DENIED", message, details)
```

<ParamField path="message" type="str" default="&#x22;Approval denied.&#x22;">
  Explanation of the denial.
</ParamField>

<ParamField path="details" type="dict | None" default="None">
  May contain the reviewer's `actor_id` and `notes`.
</ParamField>

**When raised:**

* A human reviewer calls `deny()` on an operation that had a `require_approval` decision.

***

### ProviderUnavailableError

**Code:** `PROVIDER_UNAVAILABLE`

Raised when the configured memory adapter backend is unreachable or returns an error.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class ProviderUnavailableError(MemproofError):
    def __init__(self, message: str = "Provider unavailable"):
        super().__init__("PROVIDER_UNAVAILABLE", message)
```

<ParamField path="message" type="str" default="&#x22;Provider unavailable&#x22;">
  Description of the provider failure.
</ParamField>

**When raised:**

* The LangGraph checkpoint API is unreachable.
* The OpenAI Sessions API returns a server error.
* The MCP memory server connection times out.
* Any adapter backend fails to respond.

#### Example

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import ProviderUnavailableError

try:
    result = await mp.remember(
        content="user preference",
        scope={"tenant_id": "t1", "project_id": "p1", "agent_id": "a1"},
        context={
            "actor_type": "agent", "actor_id": "a1",
            "source": "langgraph", "timestamp": "2026-01-15T10:30:00Z",
        },
    )
except ProviderUnavailableError as e:
    print(e.message)  # "Provider unavailable"
    # Retry or fall back to a different adapter
```

***

### InternalError

**Code:** `INTERNAL_ERROR`

Raised when an unexpected internal error occurs within the Memproof pipeline.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
class InternalError(MemproofError):
    def __init__(self, message: str = "Internal error"):
        super().__init__("INTERNAL_ERROR", message)
```

<ParamField path="message" type="str" default="&#x22;Internal error&#x22;">
  Description of the internal error.
</ParamField>

**When raised:**

* An unexpected exception occurs during orchestration that does not map to a more specific error type.

***

## Error Handling Patterns

### Catch-All

Catch `MemproofError` to handle any Memproof exception in a single block:

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import MemproofError

try:
    result = await mp.remember(content="hello", scope=scope, context=ctx)
except MemproofError as e:
    log.error("Memproof error", code=e.code, message=e.message, details=e.details)
```

### Granular Handling

Handle specific error types differently:

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from memproof import (
    PolicyDeniedError,
    QuarantinedError,
    NotFoundError,
    ProviderUnavailableError,
    MemproofError,
)

try:
    result = await mp.remember(content="user data", scope=scope, context=ctx)
except PolicyDeniedError as e:
    # Policy blocked the operation -- log and inform the caller
    log.warning("Policy denied", reason_codes=e.details)
except QuarantinedError as e:
    # Operation held for review -- track the operation_id
    log.info("Quarantined", operation_id=e.details.get("operation_id"))
except ProviderUnavailableError:
    # Backend is down -- retry with backoff
    await retry_with_backoff(...)
except MemproofError as e:
    # Any other Memproof error
    log.error("Unexpected Memproof error", code=e.code, message=e.message)
```

### Error Code Reference

| Error Class                | Code                   | Default Message                                |
| -------------------------- | ---------------------- | ---------------------------------------------- |
| `ValidationError`          | `VALIDATION_ERROR`     | *(varies -- describes the validation failure)* |
| `NotFoundError`            | `NOT_FOUND`            | `"Not found"`                                  |
| `ConflictError`            | `CONFLICT`             | `"Conflict"`                                   |
| `PolicyDeniedError`        | `POLICY_DENIED`        | `"Operation denied by policy rule."`           |
| `QuarantinedError`         | `QUARANTINED`          | `"Operation quarantined."`                     |
| `ApprovalDeniedError`      | `APPROVAL_DENIED`      | `"Approval denied."`                           |
| `ProviderUnavailableError` | `PROVIDER_UNAVAILABLE` | `"Provider unavailable"`                       |
| `InternalError`            | `INTERNAL_ERROR`       | `"Internal error"`                             |
