Errors¶
The ActiveGraphError hierarchy plus the cross-cutting helpers.
For the format spec and the events-not-exceptions principle see
concepts/failure-model. For
per-error recovery prose see the
error reference catalog
(one page per leaf).
Hierarchy root¶
Bases: Exception
Root of every framework error. CONTRACT v1.0 #4.
Subclasses construct by passing a one-line summary plus the three
structured fields (what_failed, why, how_to_fix) and any
error-specific context. __str__ produces the locked format; the
structured fields stay accessible programmatically for tools that
want to render errors differently (a doc-site error catalog, a
machine-readable failure log, etc.).
__init__(summary_or_message, *, what_failed=None, why=None, how_to_fix=None, context=None)
¶
Two construction modes during the v1.0 transition:
- Structured (the v1.0 target): pass
summaryplus the three named fields.__str__produces the locked format. - Legacy: pass a single positional message. Used by error
leaves that have not yet migrated under the v1.0 PR series.
__str__returns the message verbatim — format-noncompliant but valid Python, so existing raises keep working.
PR-A converts the ReplayError leaves (the reference category). PR-B through PR-F convert the rest one PR at a time. The legacy branch goes away once every leaf is migrated; until then this gateway is the bridge.
is_structured()
¶
True when the three structured fields are populated. Used by the format snapshot tests and the docs catalog to filter out leaves that have not yet migrated to the v1.0 format.
Category bases¶
Bases: ActiveGraphError
Runtime construction problems: invalid budget, malformed store URL, missing required configuration. Fires before any work runs.
Bases: ActiveGraphError
Behavior, tool, or pack registration problems: conflicts at registration time, version mismatches, missing providers, unknown tools. Fires at registration / pack-load time.
Bases: ActiveGraphError
Runtime execution problems: behavior failures, budget exhausted,
tool failures during a goal run. Named ExecutionError (not
RuntimeError) because Python already has builtin RuntimeError and
shadowing the builtin produces confusing stack traces.
Bases: ActiveGraphError
Replay and fork problems: cache hash mismatches, type-stream divergence between recorded and re-run event logs. Fires only during replay / fork; never during a fresh run.
Bases: ActiveGraphError
Persistence problems: failed writes, malformed event payloads on deserialize, schema version mismatches.
Bases: ActiveGraphError
Pattern subscription problems: invalid Cypher syntax, unsupported features, malformed WHERE clauses at registration time.
Bases: ActiveGraphError
Pack-specific problems at runtime (not registration): schema
violations on add_object after pack load, pack-state inconsistencies.
Registration-time pack errors live under :class:RegistrationError
instead.
Cross-cutting¶
Bases: RegistrationError, ImportError
A subsystem requires an optional Python package that isn't installed.
Used by the Postgres store, the Prometheus metrics backend, and the
Pack format (which requires Pydantic). Multi-inherits :class:ImportError
so user code that catches the builtin around optional-dep imports
continues to work. v1.0 PR-E.
Construct with the missing package name and the activegraph extras name that bundles it; the structured message walks the user through the install line.
Replay¶
Bases: ReplayError
Raised when a replay (replay_strict=True) or a fork produces an
event stream that does not match the recorded log.
event_id pins the first divergence point so an operator can jump
directly to it. expected and actual describe what was
recorded vs. what the live re-run produced; one is None when the
re-run finished early or produced an extra event with no recorded
counterpart.
Pattern¶
Bases: PatternError, SyntaxError
Pattern uses syntax outside the v0.7 Cypher subset.
Multi-inherits :class:SyntaxError so existing user code that
catches SyntaxError around pattern compilation keeps working.
The v1.0 structured-format superclass is :class:PatternError,
which is itself an :class:ActiveGraphError.
Construct via :meth:refused_feature or :meth:syntax_error —
the factory class methods produce the canonical voice for the two
failure modes (a refused-but-recognized Cypher feature vs. a
parser-level syntax error). Direct construction with the structured
fields is supported for one-off cases.
refused_feature(*, feature, workaround, at=None, why=None)
classmethod
¶
The canonical case: a recognized Cypher feature that the v0.7 subset deliberately refuses, with a documented workaround.
Use for OR, OPTIONAL MATCH, variable-length paths, undirected
relationships, WITH, RETURN, CREATE, MERGE, etc. The feature
argument is included in the summary verbatim, so the substring
is the same string an operator would search a log for.
syntax_error(*, what, at=None, expected=None, got=None)
classmethod
¶
Parser-level error: the pattern does not parse at all (vs. parses-but-uses-refused-feature). Recovery points the developer at the offending token / position.
Storage¶
Bases: StorageError, TypeError
Raised at emit-time when a payload value cannot be JSON-encoded.
Multi-inherits :class:TypeError so user code that does
except TypeError around emit/append calls keeps working.
Distinct from :class:CorruptedEventPayloadError — this is the
encode-side failure (Python value cannot be made into JSON);
that one is the decode-side failure (JSON bytes cannot be made
into a Python value).
Bases: StorageError, ValueError
Raised when a URL is missing a scheme, has an unsupported scheme, or is otherwise malformed.
Multi-inherits :class:ValueError so user code that catches
ValueError around URL parsing keeps working. The message always
points the user at a concrete fix — bare paths get
sqlite:///<that path>, unsupported schemes get the list of
supported ones.
Bases: StorageError
The store's recorded schema_version doesn't match what this
activegraph build expects.
Fires on store open. The store file is intact; it was just written by a different (older or newer) activegraph build. Recovery is one of three things: upgrade activegraph, downgrade the store via migration, or migrate the run to a fresh store with the current build.
Bases: StorageError, KeyError
An event id wasn't found in the run's event log.
Multi-inherits :class:KeyError so user code that does
except KeyError around store lookups keeps working. Fires from
every store.get_event(event_id) and from the fork primitive
when --at-event names a missing id.
Bases: StorageError, ValueError
Two events with the same id were appended to the same run.
Multi-inherits :class:ValueError for back-compat with user code
catching ValueError around appends. Fires only on programmer error:
the runtime's id generator is monotonic so duplicates shouldn't
arise in normal use. Common cause: hand-constructing events with
fixed ids in a test fixture.
Bases: StorageError
A stored event payload couldn't be decoded as JSON.
Fires at load-time when a row's payload column contains invalid
JSON. Distinct from :class:NonSerializableEventError, which fires
at emit-time when a Python value can't be encoded to JSON.
Corruption-on-load means the bytes on disk don't parse — a
different failure mode requiring a different recovery.
Execution¶
Bases: ExecutionError, Exception
Structured failure from inside an @llm_behavior wrapper.
The runtime's _invoke catch reads reason and payload_extras
off this exception and includes them in the emitted
behavior.failed event. Other exception types fall through to
the existing CONTRACT v0.6 #13 path unchanged.
Constructor signature (reason, message, *, payload_extras=) is
preserved from v0.6 so the ~8 internal raise sites in providers do
not change. The structured-format fields are auto-derived from
reason via the per-reason prose table above.
Bases: ExecutionError, Exception
Structured failure from inside a tool invocation.
reason must be one of the v0.7 codes:
tool.timeout, tool.network_error, tool.invalid_input, tool.invalid_output, tool.execution_error, tool.unknown_tool, tool.fixture_missing, budget.tool_calls_exhausted, budget.cost_exhausted.
Constructor signature (reason, message, *, payload_extras=) is
preserved from v0.7 so the internal raise sites in tool bodies do
not change. The structured-format fields are auto-derived from
reason via _TOOL_REASON_PROSE.
Bases: ExecutionError, RuntimeError
Raised when an LLM response calls a tool the behavior didn't declare.
The runtime catches it during the LLM tool-loop and surfaces it as
behavior.failed reason="tool.unknown_tool". Multi-inherits
RuntimeError so user code that catches RuntimeError around runtime
operations continues to work.
Bases: ExecutionError, LookupError
Pending-approval lookup miss.
Fires from runtime.approve(approval_id) when the id doesn't
refer to any currently-pending approval. Multi-inherits
:class:LookupError so user code that does except LookupError
around the approval API continues to work.
Bases: ExecutionError, RuntimeError
ctx.propose_object (or another ctx method that requires the
runtime) was called from a behavior whose context isn't bound to a
runtime.
Fires at execution time, inside a running behavior — the caller is
the behavior body that invoked the ctx method, not the framework's
construction code. Multi-inherits :class:RuntimeError for
back-compat.
Bases: ExecutionError, ValueError
graph.apply_patch(patch_id) was called on a patch that isn't
in "proposed" state.
Patches go through proposed → applied (success) or proposed →
rejected (policy or behavior rejection). Calling apply_patch
on an already-applied or already-rejected patch is a programmer
error in the calling code path; the framework refuses rather than
re-apply or silently no-op. Multi-inherits :class:ValueError.
Bases: ExecutionError, ValueError
A framework-internal evaluator received input it does not recognize. Should not fire in normal use — the framework's parsers produce a closed set of operators / AST nodes, and an unrecognized one means either drift between parser and evaluator or external AST construction that bypassed the parser.
Multi-inherits :class:ValueError so user code that catches the
builtin around view operations continues to work. Used by
activegraph/core/graph.py for the view-filter evaluator; the
pattern-subscription evaluator's two internal-bug raises stay as
:class:UnsupportedPatternError (the natural category) but use
the same :func:activegraph.errors.internal_bug_fields helper so
the prose is uniform across all three sites.
Registration¶
Bases: RegistrationError, RuntimeError
Raised when an @llm_behavior is invoked but no LLM provider is wired on the Runtime.
Fires at registration / startup, not at every invocation — the
runtime validates the configuration once. Multi-inherits
:class:RuntimeError for back-compat with user code catching the
builtin around runtime construction.
Bases: RegistrationError, RuntimeError
An @llm_behavior declares a tool name the runtime cannot find
in its tool registry at startup.
Fires at construction time, not at LLM-call time — the runtime
validates the declared tools once when the behavior registers.
Multi-inherits :class:RuntimeError for back-compat.
Bases: RegistrationError, LookupError
runtime.get_behavior(name) could not resolve the name to a
registered behavior.
Multi-inherits :class:LookupError so user code that catches the
builtin around behavior lookups continues to work.
Bases: RegistrationError, ValueError
A short behavior name resolves to more than one loaded pack.
Fires only when both packs declare a behavior under the same short
name. The user is asked to disambiguate by using the canonical
pack_name.behavior_name form. CONTRACT v0.9 #8.
Bases: RegistrationError, LookupError
runtime.get_tool(name) could not resolve the name to a
registered tool.
Symmetric with :class:BehaviorNotFoundError. Multi-inherits
:class:LookupError for back-compat.
Bases: RegistrationError, ValueError
A short tool name resolves to more than one loaded pack.
Symmetric with :class:AmbiguousBehaviorError. CONTRACT v0.9 #9.
Bases: RegistrationError, ValueError
activate_after= on a @behavior / @llm_behavior decorator was
passed an unparseable or out-of-range value.
Multi-inherits :class:ValueError for back-compat with user code
catching the builtin around behavior registration.
Bases: RegistrationError, TypeError
A value passed to Runtime(tools=[...]) is not a Tool instance.
Common cause: the developer passed a bare function instead of one
decorated with @tool. Multi-inherits :class:TypeError for
back-compat.
Bases: RegistrationError, LookupError
activegraph.packs.load_by_name(name) could not find an installed
pack with that name in the entry-point registry.
Multi-inherits :class:LookupError for back-compat with user code
catching the builtin around pack discovery.
Bases: RegistrationError, PackError
Two loaded packs conflict on a declared identifier.
Raised at runtime.load_pack time. Pre-mutation: a failed
load_pack call leaves the runtime exactly as it was.
Bases: RegistrationError, PackError
Same pack name loaded with two different versions.
A runtime cannot hold two versions of the same pack. Pre-mutation,
same as PackConflictError.
Pack¶
Bases: PackError, ValueError
graph.add_object or graph.add_relation data failed schema
validation against a loaded pack's declared type.
Runtime-shape error (fires at add_object / add_relation, not at
pack load), so stays under PackError only — this is the lone
runtime-shape leaf in the PackError category. Subclass of
:class:ValueError so user code catching the builtin around graph
mutations continues to work.
v1.0 PR-G migrated to structured format. Three call sites are served by three factory class methods (object validation, relation source-type, relation target-type) so the recovery prose can be specific to each shape. Direct construction with the structured fields is also supported.
for_object(*, object_type, validation_error, pack_name=None)
classmethod
¶
Object data failed the pack's declared schema validation.
for_relation_source(*, relation_type, source_type, allowed, pack_name=None)
classmethod
¶
Relation source object type isn't in the allowed list.
for_relation_target(*, relation_type, target_type, allowed, pack_name=None)
classmethod
¶
Relation target object type isn't in the allowed list.
Bases: RegistrationError, PackError
A Pack(...) constructor argument failed validation.
Raised at construction time, not at load time. Covers things like duplicate behavior names, an invalid pack name, an unhashable settings_schema, etc. Multi-inherits RegistrationError (v1.0 PR-E) and PackError (v0.9 base).
Bases: RegistrationError, PackError
runtime.load_pack(pack) called without settings= for a pack
whose settings_schema doesn't accept no-arg construction.
Bases: RegistrationError, PackError
A prompt file is malformed, missing required frontmatter, or unreadable. Pack registration time.
Configuration¶
Bases: ConfigurationError, ValueError
Caller-provided configuration is invalid (conflicting arguments, missing required argument, out-of-range value).
Multi-inherits :class:ValueError so user code that catches the
builtin around runtime construction or method calls keeps working.
Construct with a one-line summary plus the three structured
fields. The recovery prose is per-call-site, not table-driven —
each configuration mistake has a different fix.
Bases: ConfigurationError, TypeError
A value passed to a constructor or method has the wrong type.
Multi-inherits :class:TypeError. Used when the framework's
contract is type-based (e.g., :class:PostgresEventStore accepts
a URL string, a psycopg.Connection, or a psycopg_pool.ConnectionPool —
anything else is refused at construction).
Bases: ConfigurationError, RuntimeError
An operation requires a runtime state that isn't satisfied — either a state that must be set but isn't, or a state that mustn't be set but is.
Examples: runtime.fork() requires a SQLite-backed runtime;
graph.attach_store() requires no existing store. Multi-inherits
:class:RuntimeError for back-compat.