Exceptions¶
All library exceptions inherit from MixpanelHeadlessError, enabling callers to catch all library errors with a single except clause.
Explore on DeepWiki
Ask questions about specific exceptions, error recovery patterns, or debugging strategies.
Exception Hierarchy¶
MixpanelHeadlessError
├── ConfigError
│ ├── AccountNotFoundError
│ ├── AccountExistsError
│ ├── AccountInUseError
│ ├── InvalidArgumentError
│ └── ProjectNotFoundError
├── APIError
│ ├── AuthenticationError
│ ├── RateLimitError
│ ├── QueryError
│ └── ServerError
├── OAuthError
│ └── RegionProbeError
│ └── RegionProbeNetworkError
├── WorkspaceScopeError
└── BusinessContextValidationError
Catching Errors¶
import mixpanel_headless as mp
try:
ws = mp.Workspace()
result = ws.segmentation(event="Purchase", from_date="2025-01-01", to_date="2025-01-31")
except mp.AuthenticationError as e:
print(f"Auth failed: {e.message}")
except mp.RateLimitError as e:
print(f"Rate limited, retry after {e.retry_after}s")
except mp.OAuthError as e:
print(f"OAuth error [{e.code}]: {e.message}")
except mp.WorkspaceScopeError as e:
print(f"Workspace error [{e.code}]: {e.message}")
except mp.AccountInUseError as e:
print(f"Account '{e.account_name}' referenced by targets: {e.referenced_by}")
except mp.MixpanelHeadlessError as e:
print(f"Error [{e.code}]: {e.message}")
Base Exception¶
mixpanel_headless.MixpanelHeadlessError
¶
MixpanelHeadlessError(
message: str,
code: str = "UNKNOWN_ERROR",
details: dict[str, Any] | None = None,
)
Bases: Exception
Base exception for all mixpanel_headless errors.
All library exceptions inherit from this class, allowing callers to: - Catch all library errors: except MixpanelHeadlessError - Handle specific errors: except AccountNotFoundError - Serialize errors: error.to_dict()
Initialize exception.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
code
|
Machine-readable error code for programmatic handling.
TYPE:
|
details
|
Additional structured data about the error.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
API Exceptions¶
mixpanel_headless.APIError
¶
APIError(
message: str,
*,
status_code: int,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
request_body: dict[str, Any] | None = None,
code: str = "API_ERROR",
)
Bases: MixpanelHeadlessError
Base class for Mixpanel API HTTP errors.
Provides structured access to HTTP request/response context for debugging and automated recovery by AI agents. All API-related exceptions inherit from this class, enabling agents to:
- Understand what went wrong (status code, error message)
- See exactly what was sent (request method, URL, params, body)
- See exactly what came back (response body, headers)
- Modify their approach and retry autonomously
Example
Initialize APIError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
status_code
|
HTTP status code from response.
TYPE:
|
response_body
|
Raw response body (string or parsed dict).
TYPE:
|
request_method
|
HTTP method used (GET, POST).
TYPE:
|
request_url
|
Full request URL.
TYPE:
|
request_params
|
Query parameters sent.
TYPE:
|
request_body
|
Request body sent (for POST requests).
TYPE:
|
code
|
Machine-readable error code.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
response_body
property
¶
Raw response body (string or parsed dict).
mixpanel_headless.AuthenticationError
¶
AuthenticationError(
message: str = "Authentication failed",
*,
status_code: int = 401,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
)
Bases: APIError
Authentication with Mixpanel API failed (HTTP 401).
Raised when credentials are invalid, expired, or lack required permissions. Inherits from APIError to provide full request/response context.
Example
Initialize AuthenticationError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
status_code
|
HTTP status code (default 401).
TYPE:
|
response_body
|
Raw response body.
TYPE:
|
request_method
|
HTTP method used.
TYPE:
|
request_url
|
Full request URL.
TYPE:
|
request_params
|
Query parameters sent.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.RateLimitError
¶
RateLimitError(
message: str = "Rate limit exceeded",
*,
retry_after: int | None = None,
status_code: int = 429,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
project_id: str | None = None,
)
Bases: APIError
Mixpanel API rate limit exceeded (HTTP 429).
Raised when the API returns a 429 status. The retry_after property indicates when the request can be retried. Inherits from APIError to provide full request context for debugging.
Example
Initialize RateLimitError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
retry_after
|
Seconds until retry is allowed (from Retry-After header).
TYPE:
|
status_code
|
HTTP status code (default 429).
TYPE:
|
response_body
|
Raw response body.
TYPE:
|
request_method
|
HTTP method used.
TYPE:
|
request_url
|
Full request URL.
TYPE:
|
request_params
|
Query parameters sent.
TYPE:
|
project_id
|
Mixpanel project id active when the limit was hit, used
to prefill the rate-limit-increase request form.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
project_id
property
¶
Mixpanel project id active when the rate limit was hit, if known.
rate_limit_form_url
property
¶
URL to request a rate-limit increase.
Returns the project-prefilled Google Form URL when the project id is known (so the lead is attributed to a project), otherwise the short form link. Handy for surfacing in scripts or notebooks that catch this error.
| RETURNS | DESCRIPTION |
|---|---|
str
|
The rate-limit-increase request form URL. |
mixpanel_headless.QueryError
¶
QueryError(
message: str = "Query execution failed",
*,
status_code: int = 400,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
request_body: dict[str, Any] | None = None,
)
Bases: APIError
Query execution failed (HTTP 400 or query-specific error).
Raised when an API query fails due to invalid parameters, syntax errors, or other query-specific issues. Inherits from APIError to provide full request/response context for debugging.
Example
Initialize QueryError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
status_code
|
HTTP status code (default 400).
TYPE:
|
response_body
|
Raw response body with error details.
TYPE:
|
request_method
|
HTTP method used.
TYPE:
|
request_url
|
Full request URL.
TYPE:
|
request_params
|
Query parameters sent.
TYPE:
|
request_body
|
Request body sent (for POST).
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.ServerError
¶
ServerError(
message: str = "Server error",
*,
status_code: int = 500,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
request_body: dict[str, Any] | None = None,
)
Bases: APIError
Mixpanel server error (HTTP 5xx).
Raised when the Mixpanel API returns a server error. These are typically transient issues that may succeed on retry. The response_body property contains the full error details from Mixpanel, which often include actionable information (e.g., "unit and interval both specified").
Example
Initialize ServerError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
status_code
|
HTTP status code (5xx).
TYPE:
|
response_body
|
Raw response body with error details.
TYPE:
|
request_method
|
HTTP method used.
TYPE:
|
request_url
|
Full request URL.
TYPE:
|
request_params
|
Query parameters sent.
TYPE:
|
request_body
|
Request body sent (for POST).
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
Configuration Exceptions¶
mixpanel_headless.ConfigError
¶
Bases: MixpanelHeadlessError
Base for configuration-related errors.
Raised when there's a problem with configuration files, environment variables, or credential resolution.
Initialize ConfigError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
details
|
Additional structured data.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.AccountNotFoundError
¶
Bases: ConfigError
Named account does not exist in configuration.
Raised when attempting to access an account that hasn't been configured. The available_accounts property lists valid account names to help users.
Initialize AccountNotFoundError.
| PARAMETER | DESCRIPTION |
|---|---|
account_name
|
The requested account name that wasn't found.
TYPE:
|
available_accounts
|
List of valid account names for suggestions.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.AccountExistsError
¶
Bases: ConfigError
Account name already exists in configuration.
Raised when attempting to add an account with a name that's already in use.
Initialize AccountExistsError.
| PARAMETER | DESCRIPTION |
|---|---|
account_name
|
The conflicting account name.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.AccountInUseError
¶
Bases: ConfigError
Account is referenced by one or more targets and cannot be removed.
Raised by mp.accounts.remove(name) when the account is referenced by
one or more [targets.NAME] blocks and the caller did not pass
force=True. The list of dependent target names is available in
referenced_by so callers can show a helpful error message or pass
force=True to delete the account and orphan the targets.
Initialize AccountInUseError.
| PARAMETER | DESCRIPTION |
|---|---|
account_name
|
The account that callers tried to remove.
TYPE:
|
referenced_by
|
Names of targets that reference the account.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.ProjectNotFoundError
¶
Bases: ConfigError
Raised when a specified project is not accessible.
Includes the requested project ID and optionally a list of accessible project IDs to help the user correct their selection.
Example
try:
projects = ws.projects()
match = [p for p in projects if p.id == target_id]
if not match:
raise ProjectNotFoundError(
target_id,
available_projects=[p.id for p in projects],
)
except ProjectNotFoundError as e:
print(f"Project '{e.project_id}' not found.")
if e.available_projects:
print(f"Available: {', '.join(e.available_projects)}")
Initialize ProjectNotFoundError.
| PARAMETER | DESCRIPTION |
|---|---|
project_id
|
The requested project ID that wasn't found.
TYPE:
|
available_projects
|
List of accessible project IDs for suggestions.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
InvalidArgumentError¶
Raised by accounts.login_unified (and the CLI's mp login) when a public-API call combines mutually incompatible arguments. Subclass of ConfigError. The CLI maps this to exit code 3 (INVALID_ARGS) instead of the generic 1.
violation |
Raised When |
|---|---|
mutually_exclusive |
--service-account + --token-env (or equivalent kwargs) |
no_browser_misuse |
--no-browser against a non-browser auth type |
secret_stdin_misuse |
--secret-stdin against a non-SA auth type |
The details dict carries violation and (when detection ran) detected_auth_type. Pattern-match by class so non-CLI callers (Cowork's auth_manager.py, JSON consumers) can dispatch without parsing the human message.
mixpanel_headless.InvalidArgumentError
¶
InvalidArgumentError(
message: str,
*,
violation: Literal[
"mutually_exclusive", "no_browser_misuse", "secret_stdin_misuse"
],
detected_auth_type: str | None = None,
)
Bases: ConfigError
Raised when a public API call combines mutually incompatible arguments.
Carries a violation discriminator and the resolved
detected_auth_type so non-CLI callers (Cowork's auth_manager.py,
JSON consumers) can dispatch programmatically without parsing the
human message. The CLI handle_errors decorator maps this subclass
to ExitCode.INVALID_ARGS (3) instead of the generic
GENERAL_ERROR (1) that ConfigError would otherwise produce.
Used by accounts.login_unified for the three documented
flag-combination rejections (043 contract, cli-commands.md §5):
--service-account + --token-env, --no-browser against a
non-browser auth type, and --secret-stdin against a non-SA
auth type.
Example
Initialize InvalidArgumentError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
violation
|
Discriminator for the kind of misuse. One of
TYPE:
|
detected_auth_type
|
The auth type the orchestrator resolved
from the supplied flags / env.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
OAuth Exceptions¶
Raised during OAuth 2.0 PKCE authentication flows and the mp login region probe.
| Error Code | Raised When |
|---|---|
OAUTH_TOKEN_ERROR |
Token exchange fails |
OAUTH_REFRESH_ERROR |
Token refresh fails (transient) |
OAUTH_REFRESH_REVOKED |
Refresh token rejected by IdP as invalid_grant (re-run mp login --name NAME) |
OAUTH_REGISTRATION_ERROR |
Dynamic client registration fails |
OAUTH_TIMEOUT |
Callback server times out waiting for authorization |
OAUTH_PORT_ERROR |
Cannot bind to a local port for the callback server |
OAUTH_BROWSER_ERROR |
Cannot open the authorization URL in the browser |
OAUTH_REGION_PROBE_FAILED |
mp login probed every region and none accepted the credential — see RegionProbeError below |
OAUTH_NETWORK_UNREACHABLE |
Every region probe failed at the network layer (DNS / TLS / connect refused) — see RegionProbeNetworkError below |
mixpanel_headless.OAuthError
¶
Bases: MixpanelHeadlessError
OAuth authentication flow error.
Raised for failures during the OAuth 2.0 PKCE flow, including token exchange, token refresh, client registration, callback timeout, port unavailability, and browser launch failures.
Error codes: - OAUTH_TOKEN_ERROR: Token exchange or validation failed - OAUTH_REFRESH_ERROR: Token refresh failed - OAUTH_REGISTRATION_ERROR: Dynamic Client Registration failed - OAUTH_TIMEOUT: Callback server timed out waiting for authorization - OAUTH_PORT_ERROR: All callback ports are occupied - OAUTH_BROWSER_ERROR: Could not open browser for authorization
Example
Initialize OAuthError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
code
|
Machine-readable error code. One of: OAUTH_TOKEN_ERROR, OAUTH_REFRESH_ERROR, OAUTH_REGISTRATION_ERROR, OAUTH_TIMEOUT, OAUTH_PORT_ERROR, OAUTH_BROWSER_ERROR.
TYPE:
|
details
|
Additional structured data about the error.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
RegionProbeError¶
Raised by mp login (and accounts.login_unified) when the us → eu → in region probe fails for every region. Subclass of OAuthError. The attempts attribute carries the full (region, status_code, error_body) list; status 0 indicates a network-layer failure (DNS / TLS / connect refused) — those cases raise RegionProbeNetworkError (subclass) so the CLI can render a different remediation hint.
import mixpanel_headless as mp
try:
mp.accounts.login_unified()
except mp.RegionProbeNetworkError as exc:
print("Could not reach any Mixpanel region. Check connectivity.")
for region, status, body in exc.attempts:
print(f" {region}: {body}")
except mp.RegionProbeError as exc:
print("Credential not valid in any region.")
for region, status, body in exc.attempts:
print(f" {region}: {status} {body}")
mixpanel_headless.RegionProbeError
¶
RegionProbeError(
message: str,
*,
attempts: list[tuple[Region, int, str]],
code: str = "OAUTH_REGION_PROBE_FAILED",
)
Bases: OAuthError
Raised when no region accepts the credential during region probing.
The region probe walks a configured order (default us → eu →
in) against /api/app/me, returning the first 200. When every
probe attempt fails, this exception is raised carrying the full
attempt list for diagnostic and telemetry use.
A status code of 0 indicates the request never reached the server
(network error); the third tuple element carries the failure detail
(HTTP response text or the network error reason).
See :class:RegionProbeNetworkError for the all-network-error
subclass — the probe distinguishes "credential rejected" from
"could not reach any region" so the CLI can render different
remediation hints.
Example
Initialize RegionProbeError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
attempts
|
Ordered list of
TYPE:
|
code
|
Machine-readable error code. Defaults to
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
attempts
property
¶
Ordered list of (region, status_code, error_body) tuples.
to_dict
¶
Serialize the exception to a JSON-friendly dict.
Includes attempts at the top level so consumers can inspect
the per-region probe outcomes without unpacking details.
| RETURNS | DESCRIPTION |
|---|---|
dict[str, Any]
|
Dictionary with keys |
dict[str, Any]
|
|
dict[str, Any]
|
|
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.RegionProbeNetworkError
¶
Bases: RegionProbeError
Raised when every region probe attempt failed at the network layer.
Subclass of :class:RegionProbeError used when ALL recorded
attempts have status_code == 0 — i.e. the credential was never
actually evaluated because no region was reachable (DNS failure,
TLS rejection, captive portal, no internet). The CLI catches this
before the generic RegionProbeError so it can render "could
not reach any Mixpanel region" instead of "credential not valid",
which would mislead a user who is actually offline.
Carries the same attempts shape as the parent so existing
consumers can render the per-region detail without changes.
Initialize RegionProbeNetworkError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
attempts
|
Ordered list of
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
Workspace / Organization Scope Exceptions¶
Raised when an auth-axis identifier (workspace or organization) cannot be resolved during App API requests.
| Error Code | Raised When |
|---|---|
NO_WORKSPACES |
No workspaces found for the project |
AMBIGUOUS_WORKSPACE |
Multiple workspaces found and none is marked as default |
WORKSPACE_NOT_FOUND |
Specified workspace ID does not exist |
ORGANIZATION_AMBIGUOUS |
An org-scoped business-context call could not auto-resolve the organization (active project absent from /me AND >1 accessible organization). details carries project_id and available_organizations. Pass organization_id=N explicitly to bypass auto-resolution. |
mixpanel_headless.WorkspaceScopeError
¶
WorkspaceScopeError(
message: str,
code: str = "NO_WORKSPACES",
details: dict[str, Any] | None = None,
)
Bases: MixpanelHeadlessError
Scope resolution error (workspace or organization).
Raised when an auth-axis identifier cannot be resolved during App
API requests. Originally introduced for workspace resolution; also
raised when the organization ID for an org-scoped business-context
call cannot be auto-derived from the cached /me response.
Error codes:
- NO_WORKSPACES: Project has no accessible workspaces
- AMBIGUOUS_WORKSPACE: Multiple workspaces, none default; must specify --workspace-id
- WORKSPACE_NOT_FOUND: Explicit workspace ID doesn't match any workspace
- ORGANIZATION_AMBIGUOUS: Cannot auto-resolve the organization for an
org-scoped call (active project absent from /me AND >1 accessible
organization). The details dict carries project_id and
available_organizations. Pass organization_id=N explicitly
to bypass auto-resolution.
Example
Initialize WorkspaceScopeError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
code
|
Machine-readable error code. One of: NO_WORKSPACES, AMBIGUOUS_WORKSPACE, WORKSPACE_NOT_FOUND, ORGANIZATION_AMBIGUOUS.
TYPE:
|
details
|
Additional structured data about the error.
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
Business Context Exceptions¶
Raised by Workspace.set_business_context() when content exceeds the 50,000-character cap. The check runs before the HTTP call, so callers fail fast and don't waste a round-trip; the server enforces the same limit and would otherwise return QueryError (HTTP 400). See the Business Context guide for usage.
| Error Code | Raised When |
|---|---|
BUSINESS_CONTEXT_TOO_LONG |
len(content) > BUSINESS_CONTEXT_MAX_CHARS (50,000) |
The details dict carries length (the actual content length) and max (the configured limit) for programmatic recovery.
mixpanel_headless.BusinessContextValidationError
¶
Bases: MixpanelHeadlessError
Business context content failed client-side validation.
Raised by Workspace.set_business_context() when the supplied
content exceeds BUSINESS_CONTEXT_MAX_CHARS (50,000 characters).
The check runs before the HTTP call so callers can fail fast and
avoid a wasted round-trip — the server enforces the same limit
server-side and would otherwise return QueryError (HTTP 400).
The details dict carries length (the actual content length)
and max (the configured limit) for programmatic recovery.
Example
Initialize BusinessContextValidationError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message.
TYPE:
|
details
|
Additional structured data — typically
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
Session Replay Exceptions¶
Raised by the session-replay surface (fetch_replay(), sign_replay(), stream_replay()). SessionReplayError is the base — catch it to handle any replay failure. See the Session Replay guide.
| Exception | Raised When |
|---|---|
SessionReplayAccessError |
The project has the SESSION_RECORDING_SENSITIVE_DATA flag set and the caller lacks the sensitive_data_replay permission (HTTP 403). details carries project_id, flag, and permission_required. |
SignedURLExpiredError |
A signed CDN URL expired mid-fetch (~5-minute TTL) and re-signing was disabled or also failed. |
ReplayNotFoundError |
The replay's first CDN file returned 404 — it aged out of its retention window, was never recorded, or was deleted. |
mixpanel_headless.SessionReplayError
¶
SessionReplayError(
message: str,
*,
details: dict[str, Any] | None = None,
status_code: int | None = None,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
request_body: dict[str, Any] | None = None,
code: str | None = None,
)
Bases: APIError
Base class for session-replay-specific failures.
Subclasses cover the three replay-specific failure modes:
:class:SessionReplayAccessError (sensitive-data permission denied),
:class:SignedURLExpiredError (5-minute signed-URL TTL elapsed), and
:class:ReplayNotFoundError (CDN walker found no bytes for the
replay). All carry the standard :class:APIError HTTP context
(status_code, response_body, request_url, etc.) plus a
replay-specific details dict that the subclass merges in on top
(replay_id, project_id, flag, retention_days, …).
Catch this base class to handle any replay failure uniformly:
Example
Because :class:SessionReplayError is an :class:APIError, existing
except APIError: handlers — including the CLI handle_errors
decorator that maps HTTP failures to exit codes — continue to catch
these without modification.
Initialize SessionReplayError.
| PARAMETER | DESCRIPTION |
|---|---|
message
|
Human-readable error message; see error-messages.md for the catalog of stable wording per subclass.
TYPE:
|
details
|
Replay-specific structured context (
TYPE:
|
status_code
|
HTTP status that triggered the error. Defaults
to the subclass's
TYPE:
|
response_body
|
Raw response body for debugging.
TYPE:
|
request_method
|
HTTP method (GET, POST, …).
TYPE:
|
request_url
|
Full request URL.
TYPE:
|
request_params
|
Query parameters sent on the failing request.
TYPE:
|
request_body
|
Request body sent on the failing request.
TYPE:
|
code
|
Machine-readable error code. Defaults to the subclass's
TYPE:
|
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.SessionReplayAccessError
¶
SessionReplayAccessError(
message: str,
*,
details: dict[str, Any] | None = None,
status_code: int | None = None,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
request_body: dict[str, Any] | None = None,
code: str | None = None,
)
Bases: SessionReplayError
Project has SESSION_RECORDING_SENSITIVE_DATA enabled and caller lacks access.
Raised when the bulk-sign endpoint returns 403 with a body that
mentions the SESSION_RECORDING_SENSITIVE_DATA project flag. The
project owner can grant the sensitive_data_replay permission to
unblock the caller; a service account with that permission works too.
Details
project_id (int): The project that gated the call.
flag (str): Always "SESSION_RECORDING_SENSITIVE_DATA".
permission_required (str): Always "sensitive_data_replay".
See error-messages.md §1 for the canonical message wording.
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.SignedURLExpiredError
¶
SignedURLExpiredError(
message: str,
*,
details: dict[str, Any] | None = None,
status_code: int | None = None,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
request_body: dict[str, Any] | None = None,
code: str | None = None,
)
Bases: SessionReplayError
Signed CDN URL passed to a fetch has expired (5-minute TTL).
Raised when a CDN fetch returns 403 with an expiration body AND the
caller opted out of automatic re-signing (stream_replay with
re_sign_on_expiry=False). Re-sign via :meth:Workspace.sign_replay
and retry, or pass re_sign_on_expiry=True (the default) to let the
library re-sign transparently.
Details
replay_id (str): The replay whose URL expired.
signed_at (float): Unix seconds when the original URL was signed.
expired_at (float): Unix seconds when the URL expired
(typically signed_at + 300).
See error-messages.md §2 for the canonical message wording.
Source code in src/mixpanel_headless/exceptions.py
mixpanel_headless.ReplayNotFoundError
¶
ReplayNotFoundError(
message: str,
*,
details: dict[str, Any] | None = None,
status_code: int | None = None,
response_body: str | dict[str, Any] | None = None,
request_method: str | None = None,
request_url: str | None = None,
request_params: dict[str, Any] | None = None,
request_body: dict[str, Any] | None = None,
code: str | None = None,
)
Bases: SessionReplayError
No CDN bytes found for a requested replay.
Raised when the CDN walker hits a 404 on the very first file
(0000-N.json). The replay either aged out of its retention
window, was never recorded, or has been deleted. Mid-walk 404s are
treated as the end-of-replay sentinel and do NOT raise.
Details
replay_id (str): The replay that returned no bytes. retention_days (int): The retention window that was assumed (1, 7, 30, or 90). cdn_url_prefix (str): The CDN prefix that was walked.
See error-messages.md §3 for the canonical message wording.