Exceptions reference¶
Module: piighost.exceptions
Every error the library raises derives from PIIGhostError, so one except PIIGhostError covers the whole family. Between the root and the leaves sit the grouping classes, one per subsystem, which a caller catches to react to a stage rather than to a single failure. The module depends on nothing outside the standard library, so every class imports without an optional extra, including the errors raised by components that need one.
PIIGhostSecurityWarning is the one name in the module outside this tree. Being a warning and not an error, it is described at the end of the page.
The hierarchy¶
flowchart LR
PIIGhostError --> SpanError
SpanError --> NegativeSpanStartError
SpanError --> SpanOrderingError
PIIGhostError --> DetectionError
DetectionError --> ConfidenceError
PIIGhostError --> EntityError
EntityError --> EmptyEntityError
EntityError --> MixedLabelError
PIIGhostError --> DetectorError
DetectorError --> LabelMappingError
DetectorError --> TextTooLongError
PIIGhostError --> TextError
TextError --> EmptyFragmentError
PIIGhostError --> AnonymizerError
AnonymizerError --> OverlappingSpansError
PIIGhostError --> OverrideError
OverrideError --> ConflictingOverrideError
PIIGhostError --> GuardError
GuardError --> PIIRemainingError
PIIGhostError --> MiddlewareError
MiddlewareError --> UnrecognizableFactoryError
MiddlewareError --> InventedPlaceholderError
MiddlewareError --> MissingThreadIdError
PIIGhostError --> HasherError
HasherError --> EmptyPepperError
PIIGhostError --> CipherError
CipherError --> InvalidKeyLengthError
PIIGhostError --> ClientError
ClientError --> RemoteError
PIIGhostError --> ConfigError
ConfigError --> ConfigFileError
ConfigError --> ConfigValidationError
The PIIGhostError tree, each grouping class to the left of the errors it covers.
Of the thirty-three error classes, twenty are raised by a component and thirteen exist only to be caught. ConfigError counts on both sides, a grouping class that is also raised on its own.
Data models¶
Module: piighost.models. SpanError, DetectionError, and EntityError group the validation failures of the frozen data models. Each is raised from __post_init__, so an invalid value fails at construction and never reaches a stage.
| Exception | Raised by | Raised when |
|---|---|---|
NegativeSpanStartError |
Span.__post_init__ |
start is negative |
SpanOrderingError |
Span.__post_init__ |
end is not strictly greater than start, which describes an empty or a reversed range |
ConfidenceError |
Detection.__post_init__ |
confidence falls outside the closed range 0 to 1 |
EmptyEntityError |
Entity.__post_init__ |
the entity groups no detection |
MixedLabelError |
Entity.__post_init__ |
the grouped detections do not all share one label |
The invariants these errors enforce are in Data models, and the ports that exchange the models in Extending PIIGhost.
Detectors¶
Module: piighost.components.detector.ner. DetectorError groups two failures of BaseNERDetector, so they reach the model-backed detectors only. A regex, exact-match, composite, or chunked detector raises neither.
| Exception | Raised by | Raised when |
|---|---|---|
LabelMappingError |
BaseNERDetector.__init__ |
two external labels map to one internal label, which would make the reverse lookup ambiguous |
TextTooLongError |
BaseNERDetector, on detection |
a text exceeds max_chars while auto_chunk is off, so a prefix-only scan is refused |
Both are covered in Detectors, with the max_chars and auto_chunk arguments that govern the second.
Text helpers¶
Module: piighost.text. TextError groups the failures of the word-boundary helpers and carries one subclass.
| Exception | Raised by | Raised when |
|---|---|---|
EmptyFragmentError |
boundary_wrap, find_all_word_boundary, and ExactMatchDetector.__init__ |
the fragment searched for is empty, which would match at every position of the text |
An empty fragment would yield zero-width spans a Span refuses, so the failure would otherwise surface as a SpanOrderingError far from its cause. ExactMatchDetector checks its configured values at construction, so a config typo fails at load rather than on the first message. LLMDetector does not raise it, because a model's output is untrusted, so a blank extracted value is dropped with a warning instead.
Anonymizer¶
Module: piighost.components.anonymizer. AnonymizerError groups the render stage's failures and carries one subclass.
| Exception | Raised by | Raised when |
|---|---|---|
OverlappingSpansError |
Anonymizer.render |
two spans still overlap when the one-pass rewrite reaches them |
The disjoint-span assumption behind it is in Anonymizer, and the stage that upholds it in Pipeline.
Detection overrides¶
Module: piighost.components.override. OverrideError groups the failures of the whitelist and blacklist stage and carries one subclass.
| Exception | Raised by | Raised when |
|---|---|---|
ConflictingOverrideError |
DetectionOverride.apply |
a whitelisted span overlaps a blacklisted one under the raise conflict strategy |
The other two conflict strategies resolve the collision instead of raising. Every [override] key is in the configuration reference.
Guard rails¶
Module: piighost.pipeline. GuardError groups the guard-stage failures and carries one subclass.
| Exception | Raised by | Raised when |
|---|---|---|
PIIRemainingError |
the pipeline, after the guard stage | a guard returns a flagged verdict |
A guard raises nothing itself. It returns a verdict, and the pipeline turns a flagged one into this error, as described in Guard rails.
Integrations¶
Module: piighost.integrations. MiddlewareError groups the failures of the integration layer. The first two below come from the shared TextDeidentifier, which backs the LangChain middleware, the LlamaIndex query engine, and the Pydantic AI hooks alike. The third belongs to the LangChain middleware alone.
| Exception | Raised by | Raised when |
|---|---|---|
UnrecognizableFactoryError |
TextDeidentifier.__init__ |
the pipeline exposes no token recognizer, its placeholder factory having no re-findable grammar |
InventedPlaceholderError |
TextDeidentifier.deanonymize and deanonymize_stream |
restored text still holds a token the pipeline never issued, under the RAISE invented-placeholder strategy |
MissingThreadIdError |
the LangChain middleware, on each turn | the LangGraph config carries no thread_id while require_thread_id is set |
The three are covered in LangChain integration, with the strategies that decide whether the second is raised at all.
Crypto¶
Module: piighost.crypto. HasherError and CipherError group the constructor failures of the at-rest primitives, one subclass each.
| Exception | Raised by | Raised when |
|---|---|---|
EmptyPepperError |
BaseHasher.__init__ |
the pepper is empty, which would leave low-entropy PII brute-forceable |
InvalidKeyLengthError |
AesGcmCipher.__init__ |
the AES key is not 16, 24, or 32 bytes |
Both fail closed at construction, so a misconfigured store never starts. What these primitives protect is in Security, and the memory backends that take them in Conversation memory.
Remote client¶
Module: piighost.integrations.client. ClientError groups the remote client's failures and carries one subclass.
| Exception | Raised by | Raised when |
|---|---|---|
RemoteError |
PIIGhostClient, on every call |
the remote piighost-api answers with a non-2xx status |
The status guard is all it covers. A 2xx body missing an expected key surfaces as a KeyError, not a RemoteError. The client's methods are in API client.
Configuration¶
Module: piighost.config. ConfigError groups the load-time and build-time failures, and unlike the other grouping classes it is also raised on its own.
| Exception | Raised by | Raised when |
|---|---|---|
ConfigFileError |
load_config |
the file is missing, unreadable, or invalid TOML or JSON |
ConfigValidationError |
load_config |
the parsed data fails schema validation, wrapping pydantic's ValidationError in the library's family |
ConfigError |
load_pipeline, load_thread_pipeline, and a component config's build() |
the entry point does not match the [memory] section declared, a secret environment variable is unset or malformed, or a memory declares exactly one of a hasher and a cipher |
Catching ConfigError covers all three. Every key and every secret variable is in the configuration reference, and the piighost CLI reports the same three from validate, as described in CLI.
Errors carrying data¶
Three errors expose the values behind the failure as attributes. Every other error carries its message only.
| Exception | Attribute | Holds |
|---|---|---|
PIIRemainingError |
detections |
the residual detections behind the flag, empty when the guard is score-based and localizes nothing |
InventedPlaceholderError |
tokens |
the invented tokens, in order of appearance |
RemoteError |
status_code |
the HTTP status the server returned |
PIIGhostSecurityWarning¶
A UserWarning, outside the PIIGhostError tree, so it never fails a call and the standard warnings filters govern it. It marks a setup that runs but keeps PII readable, so a knowing choice still works while a forgotten one is loud. Two sites emit it, both at construction.
| Emitted by | Emitted when |
|---|---|
warn_plaintext, called from RedisConversationMemory and SqlAlchemyConversationMemory |
a persistent backend is built without a hasher and a cipher, so its store holds PII in clear |
BaseAnonymizationPipeline.__init__ |
no observation_redactor is set, trace_clear_text is off, and the tracer is exporting, so traces would record clear text |
The backend comparison is in Conversation memory, and the redactor in Observation.
See also¶
- Pipeline: the stage order the errors above follow.
- Guard rails: the verdict behind
PIIRemainingError. - LangChain integration: the strategies behind the middleware errors.
- Configuration reference: every key the configuration errors validate.
- Security: what the fail-closed choices protect against.