Skip to content

Error reference

Every failure Stewart reports has a reason. The exception class names the part of Stewart that failed, and $e->reason names the failure: StoreError::TypeMismatch belongs to a StoreException. Words in braces are filled in from $e->context. Handling errors explains how to catch them.

Thrown as HaClientException.

Reason Message What to do
ClosedLocally The connection was closed locally while {phase}.
ConnectTimedOut Connecting to Home Assistant at {url} timed out after {timeout}. Check home_assistant.url.
ConnectFailed Could not connect to Home Assistant at {url}: {cause}
NotConnected Not connected to Home Assistant.
SendFailed Failed to send {command}: {cause}
ClosedDuringAuthentication Home Assistant closed the connection during authentication.
ConnectionDropped The connection to Home Assistant was lost ({detail}).
MessageTooLarge Home Assistant sent a message over the size limit, so the connection was dropped. Raise home_assistant.message_size_limit or home_assistant.frame_size_limit.
ProtocolViolation Home Assistant sent {detail}.
CommandTimedOut Home Assistant did not answer {command} within {timeout}.
CommandRejected {command} failed: {detail}
CommandUnauthorized {command} failed: {detail}
CommandUnencodable {command} could not be encoded: {cause}
UnexpectedGreeting Expected auth_required from Home Assistant, got “{receivedType}”.
TokenRejected Home Assistant rejected the access token: {reason}. Check STEWART_HOME_ASSISTANT__TOKEN.
AdministratorRequired Home Assistant refused the event subscription; the access token must belong to an administrator. Update STEWART_HOME_ASSISTANT__TOKEN. Create the token from a Home Assistant administrator.
EventBacklogExceeded Event handlers are more than {limit} events behind; dropping the connection.
EventQueueReentered An event callback cannot wait for the event queue it is being delivered by.
UrlInvalid “{url}” is not a Home Assistant URL; use http://, https://, ws:// or wss:// and a host.
ComponentInstanceInvalid “{instance}” is not an instance name; use lowercase letters, digits and underscores, starting with a letter, up to 64 characters.

Thrown as CodegenException.

Reason Message What to do
SnapshotUnreadable Snapshot {path} cannot be read.
SnapshotNotJson Snapshot {path} is not valid JSON: {reason}
NotASnapshot {path} is not a snapshot; write one with stewart generate --snapshot-out.
OutputDirectoryNotCreatable Cannot create output directory {path}.
FileNotWritable Cannot write {path}.
FileNotDeletable Cannot delete {path}.
UnmarkedFileInTheWay {path} was not written by stewart generate; move it out of the output directory.
ShrinkRefused Generating would delete {deleted} of {existing} generated files; run make generate ARGS=--allow-shrink if that is intended.
HomeAssistantNotRunning Home Assistant is {state}; run stewart generate again once it has started.

Thrown as CommandException.

Reason Message What to do
Rejected {reason}

Thrown as EventFireException.

Reason Message What to do
TypeInvalid An event type must be 1 to 64 characters, got “{eventType}”.
DataInvalid Data of event {eventType} at {path} is {actualType}; expected null, a finite scalar or an array of those.
DataNotKeyed Data of event {eventType} must be keyed by name, got a list.
Rejected Event {eventType} was rejected by Home Assistant: {detail}
Unreachable Event {eventType} could not reach Home Assistant: {detail}
TimedOut Event {eventType} timed out: {detail}
Overloaded Event {eventType} was refused: {detail}

Thrown as ExposureException.

Reason Message What to do
ComponentMissing Entity {key} cannot be exposed because the stewart Home Assistant integration is not installed; see stewart status. Install the Stewart integration in Home Assistant and restart it.
ProtocolMismatch Entity {key} cannot be exposed because the stewart Home Assistant integration speaks another protocol; see stewart status. Update Stewart or the integration so both have the same version.
ComponentRefused Entity {key} cannot be exposed because Home Assistant refused the stewart integration session; see stewart status.
OutsideApp Entity {key} cannot be exposed outside an app, because its unique ID needs an app ID.
KeyInvalid Exposed entity key “{key}” is invalid; use up to {limit} lowercase letters, digits and “_”, starting with a letter.
KeyTaken App {appId} already exposes an entity with key {key}.
ConfigInvalid Home Assistant cannot use this entity configuration: {detail}
StateInvalid Home Assistant cannot use this entity state: {detail}
Removed Exposed entity {key} was removed; expose it again to use it.
Unreachable Could not reach the broker for exposed entity {key}: {detail}
TimedOut The broker did not answer for exposed entity {key} within {timeout}.

Thrown as HistoryException.

Reason Message What to do
WindowInvalid A history window must end after it starts, got {startsAt} to {endsAt}.
RecorderUnavailable History of {entityId} is unavailable because Home Assistant has no history integration loaded.
Rejected History of {entityId} was rejected by Home Assistant: {detail}
Unreachable History of {entityId} could not reach Home Assistant: {detail}
TimedOut History of {entityId} timed out: {detail}
Overloaded History of {entityId} was refused: {detail}

Thrown as IdentifierException.

Reason Message What to do
EntityIdInvalid Entity ID “{entityId}” is invalid; expected “.<object_id>” in lowercase letters, digits and “_”.
AppIdInvalid App ID “{appId}” is invalid; use lowercase letters, digits, “-” and “_”, starting with a letter.
AppIdTooLong App ID “{appId}” is longer than {limit} characters.
EntityNotGenerated Entity ID “{entityId}” is not a generated {domain} entity; run stewart generate if it is new. Fix the ID, or run make generate for a new entity.
RegistryIdEmpty {kind} ID must not be empty.

Thrown as MqttException.

Reason Message What to do
TopicInvalid MQTT topic {topic} must be non-empty UTF-8, free of +, # and NUL characters.
PayloadUnencodable MQTT payload for {topic} cannot be encoded as JSON: {cause}
PayloadNotJson MQTT payload on {topic} is not valid JSON: {cause}
NotConfigured MQTT is not configured; set mqtt.url in stewart.yaml or STEWART_MQTT__URL in .env. Set STEWART_MQTT__URL.
PublishFailed Could not hand the MQTT message for {topic} to the broker: {cause}

Thrown as RegistryEditException.

Reason Message What to do
NotFound Entity {entityId} is not in the Home Assistant entity registry.
NothingToUpdate The registry update for {entityId} changes nothing.
Rejected Home Assistant rejected the registry update for {entityId}: {detail}
Unreachable The registry update for {entityId} could not reach Home Assistant: {detail}
TimedOut The registry update for {entityId} timed out: {detail}
Overloaded The registry update for {entityId} was refused: {detail}

Thrown as ScheduleException.

Reason Message What to do
CronInvalid Cron expression “{expression}” is invalid.
EntityTimeDomainUnsupported Entity “{entityId}” holds no time; expected an input_datetime or a sensor entity.
SunLocationUnknown A {event} schedule needs a location, and Home Assistant reported none. Set a location in Home Assistant under Settings → System → General, then restart Stewart.
TimeOfDayInvalid Time of day “{value}” is invalid; expected “HH:MM” or “HH:MM:SS”.
TimeOfDayOutOfRange Time of day {unit} {value} is outside 0-{highest}.
TimeWindowEmpty Time window starts and ends at {time}; start and end must differ.

Thrown as SelectorException.

Reason Message What to do
Empty {selectorKind} cannot be empty.
RegexInvalid Regular expression selector {pattern} is invalid: {compileError}.
MqttFilterInvalid MQTT topic filter {filter} must use + and # only as whole levels, with # last.

Thrown as ServiceCallException.

Reason Message What to do
Rejected {domain}.{service} was rejected by Home Assistant: {detail} Try the same call under Developer tools → Actions in Home Assistant.
Unreachable {domain}.{service} could not reach Home Assistant: {detail}
TimedOut {domain}.{service} timed out: {detail}
Overloaded {domain}.{service} was refused: {detail} Call fewer services at once, for example one call with several targets.

Thrown as StateException.

Reason Message What to do
EntityNotFound Entity “{entityId}” does not exist in Home Assistant.
StateChangedViaEvents The “{eventType}” event is only delivered through watchStateChanges(), not watchEvents().
ThresholdHysteresisNegative The hysteresis of {usage}() is {hysteresis}; it must be zero or more.
ThresholdNotFinite The threshold of {usage}() is {threshold}; it must be a finite number.
TransitionRuleConflict whenChangedTo() takes either from: or fromAnyState:, not both.

Thrown as StoreException.

Reason Message What to do
KeyInvalid Store key “{key}” is invalid; expected a letter or digit, then up to 127 letters, digits, “.”, “_”, “:” or “-”.
ValueNotEncodable The value for key “{key}” is not JSON-encodable: {cause}
ValueNotAMap {class}::toStorage() returned a list for key “{key}”; expected a map of named fields.
NotConfigured Persistence is not configured; set persistence.url in stewart.yaml or STEWART_PERSISTENCE__URL in .env. Set STEWART_PERSISTENCE__URL.
Unreachable The store at {target} is unreachable: {detail}
Refused The store at {target} refused the operation: {detail}
TimedOut The store at {target} did not answer within {timeout}.
RecentlyFailed The store at {target} failed moments ago and is not being retried yet: {detail}
TypeMismatch Key “{key}” holds {actual}, not {expected}. Read the key with the type it was written with, or delete it.
NotIncrementable Key “{key}” cannot be incremented: {detail}
ValueNotIncrementable The stored value cannot be incremented: {detail}
ValueMalformed Key “{key}” does not hold valid JSON: {cause}
ValueRejected {class}::fromStorage() rejected the value of key “{key}” (handle the old shape or delete the key): {cause} Make fromStorage() accept the stored shape, or delete the key.

Thrown as SunException.

Reason Message What to do
CoordinateOutOfRange The {coordinate} {value} is outside -{limit} to {limit}.
LocationUnknown Home Assistant reported no location, so sun times are unknown.

Thrown as TimeException.

Reason Message What to do
DurationNegative Duration {microseconds}us is negative.
DurationNotFinite Duration {amount} is not a finite number.
DurationNotPositive The duration for {usage} must be at least 1ms.
DurationTooLarge Duration exceeds the 292-year maximum.
DurationUnparsable Duration “{text}” is invalid; expected a number and one unit, such as 500ms, 5s, 2m or 1h.
InstantUnparsable Instant “{text}” is not ISO-8601.

Thrown as TopicException.

Reason Message What to do
PayloadInvalid Topic payload at {path} is {actualType}; expected null, a finite scalar or an array of those.
PublishFailed Could not publish to topic {topic}: {cause}

Thrown as TriggerException.

Reason Message What to do
ConfigInvalid A Home Assistant trigger must be a map with a non-empty “trigger” or “platform” key.
ConfigUnencodable Trigger value at {path} cannot be encoded as JSON.
ListEmpty A trigger subscription needs at least one trigger.
TimeInvalid Trigger time “{time}” is neither HH:MM[:SS] nor an input_datetime or sensor entity.
TimePatternEmpty A time pattern trigger needs hours, minutes or seconds.
TemplateEmpty A template trigger needs a non-empty template.
ZoneInvalid Trigger zone “{zone}” is not a zone entity.
VariablesNotMap Trigger variables must be a map keyed by variable name.

Thrown as WaitException.

Reason Message What to do
Abandoned The wait ended before an event arrived, because its stream completed or its app stopped.

Thrown as MqttClientException.

Reason Message What to do
ConnectionRefused The MQTT server refused the connection: {refusal}.
ConnectionLost The MQTT connection was lost: {cause}
ConnectionClosed The MQTT connection is closed.
KeepaliveTimedOut The MQTT server left a keepalive ping unanswered for {keepalive}.
PacketMalformed The MQTT server sent a malformed {packetType} packet.
PacketUnexpected The MQTT server sent an unexpected {packetType} packet.
PacketIdsExhausted Every MQTT packet identifier is in flight.

Thrown as AppException.

Reason Message What to do
DuplicateId Automations {firstClass} and {secondClass} both use ID “{appId}”; “-” and “_” count as the same character.
DirectoryNotAutoloadable {directory} is not covered by a PSR-4 autoload rule. Add it to “autoload” in composer.json and run make install.
NotAnApp {className} has #[Automation] but does not implement {appInterface}.
NotInstantiable {className} has #[Automation] but cannot be instantiated.
IdInvalid {className}: automation ID “{appId}” is invalid; use lowercase letters, digits, “-” and “_”, starting with a letter.
InitializeTimedOut {appId} initialize() did not return within {timeout}. Raise supervision.initialize_timeout if needed.
Unknown No automation with ID “{appId}”.
Disabled Automation “{appId}” is not loaded because apps.{appId}.enabled is false.

Thrown as BrokerException.

Reason Message What to do
NoWorkersStarted None of {workers} workers could be started.
WorkerSpawnTimedOut Worker {worker} did not connect within {timeout}.

Thrown as ConfigurationException.

Reason Message What to do
SchemaViolation {cause}
ConfigFileMissing Config file {path} not found.
ConfigFileUnparsable Could not parse {path}: {cause}
ConfigFileNotAMap {path} holds {actualType}; expected a map of settings.
ValueInvalid “{value}” is not {expected}.
KeyInvalid {path} must be {expected}.
KeyParseFailed {path} is invalid: {cause}
DurationTooShort {path} is {value}; expected at least {minimum}.
DurationTooLong {path} is {value}; expected at most {maximum}.
MaxDelayBelowInitialDelay {path} is {value}; expected at least {initialDelayPath} ({initialDelay}).
RestartWindowTooShort supervision.restart_window is {window}, but the backoff for restart_attempts ({attempts}) adds up to {backoffTotal}, so a crash-looping worker is never quarantined.
HomeAssistantMissing home_assistant is not configured. Set STEWART_HOME_ASSISTANT__URL and STEWART_HOME_ASSISTANT__TOKEN.
PlaceholderUnset {setting} refers to ${{variable}}, which is not set. Set it or add a default: ${{variable}:-value}.
ControlTokenMissing control.token is required while control.listen is set; set STEWART_CONTROL__TOKEN or set control.listen to “off”.
AdminTokenMissing http.admin.token is required while http.admin.listen is set; set STEWART_HTTP__ADMIN__TOKEN or set http.admin.listen to “off”.
WorkerIndexOutOfRange App “{appId}” is pinned to worker {worker}, but the highest worker index is {highestIndex}.
AppUnknown stewart.yaml configures app “{appId}”, but no automation has that ID.
AppSelectionUnknown –only names app “{appId}”, but no automation has that ID.
EnvironmentVariableUnknown {variable} is not a Stewart setting; run stewart config:reference for all options. Fix the variable name; keys are joined by two underscores.
EnvironmentVariableTooDeep {variable} is deeper than the configuration; {valuePath} is a value, not a section.
EnvironmentVariableNamesSection {variable} names a section; set the keys under it, such as {variable}{separator}KEY.
EnvironmentValueInvalid {variable} is “{raw}”; expected {expected}.
EnvironmentValueUnparsable {variable} is not a valid inline list or map: {cause}
EnvironmentVariableConflict {variable} and {otherVariable} both set {valuePath}; keep one.
EnvironmentSecretFileUnreadable {variable} points to {path}, which cannot be read.
MqttPackageMissing mqtt.url is set, but the MQTT client is not installed; run composer require stewart-php/mqtt.

Thrown as ContainerException.

Reason Message What to do
ServiceTypeMismatch Service “{serviceId}” is {actualType}; expected {expectedType}.
BuildFailed Worker {workerId} failed to build its container: {cause}
AppInServicesFile services.php defines “{serviceId}” as automation {class}. Configure it in stewart.yaml instead.
PeerStoreWritable {class}::__construct() takes ${parameter} with #[PeerStore] as Store; type it ReadableStore.
PeerStoreAppIdInvalid {class}::__construct() takes ${parameter} with #[PeerStore]: {cause}
MessageHandlerDuplicated {firstHandler} and {secondHandler} both handle {messageClass}.
AppOptionInvalid Option “{option}” of app “{appId}” is “{value}”, which is not a valid {expectedType}.
AppOptionUnknown App “{appId}” sets option “{option}”, which matches no parameter of {class}::__construct(). Rename the option in stewart.yaml to match a constructor parameter.
AppOptionMissing App “{appId}” needs option “{option}”; {class}::__construct() takes ${option} with no default. Set the option, or give the parameter a default.
AppOptionAmbiguous App “{appId}” sets option “{option}”, which matches parameters {parameters} of {class}::__construct(); use the exact name.
AppOptionRepeated App “{appId}” sets ${parameter} of {class}::__construct() twice, as options “{firstOption}” and “{secondOption}”.
AppBuildFailed App “{appId}” cannot be built: {cause}
AppClassMissing App “{appId}” names class {class}, which cannot be loaded.
ServicesFileMissing Services file {path} no longer exists.

Thrown as ControlException.

Reason Message What to do
SocketInUse Another daemon is already listening on {address}. Stop it or change control.listen.
SocketUnremovable Could not remove the stale control socket {path}.
SocketDirectoryNotCreatable Could not create control socket directory {directory}.
SocketPathNotASocket The control socket path {path} exists and is not a socket.
FrameNotJson Frame is not JSON: {cause}
FrameNotAnObject Frame is {actualType}; expected a JSON object.
FrameUnencodable Could not encode {frameClass}: {cause}
FrameClassUnknown Unknown frame {frameClass}.
FrameUndecodable Could not decode the “{frameType}” control frame: {cause}
ConfigUnavailable Could not read control.listen and control.token (pass –address and –token): {cause}
ControlDisabled The configuration sets control.listen to off; pass –address.
TokenMissing No control token; set STEWART_CONTROL__TOKEN or pass –token.
ConnectionRejected The broker refused the connection: {reason}
UnexpectedGreeting The broker sent {frameClass} instead of a welcome.
ProtocolMismatch Broker speaks control protocol {brokerProtocol}, this client {clientProtocol}.
BrokerHungUp The broker hung up before the session ended.
UnexpectedFrame The broker sent {frameClass} instead of {expectedFrameClass}.
RequestTimedOut The broker did not answer within {timeout}.
RequestUnexpected The control session expects a request, not {frameClass}.
RequestFailed The broker refused the request: {message}
RequestUnanswerable The broker could not answer the request: {cause}

Thrown as DeployException.

Reason Message What to do
CommitIdInvalid “{value}” is not a commit hash.
CommandTimedOut {command} did not finish within {timeout}.
CommandFailed {command} failed with exit code {exitCode}: {detail}
PrepareOutputUnexpected release-prepare printed “{output}” instead of a commit and its state.

Thrown as TransportException.

Reason Message What to do
Closed Transport is closed.
SendFailed Failed to send to peer: {cause}
Unencodable Could not encode {messageClass} for IPC: {cause}
PeerDisconnected Peer disconnected: {cause}
ReceiveFailed Failed to receive from peer: {cause}
UnexpectedMessage Expected a JSON frame, got {actualType}.
UndecodableFrame Could not decode “{messageType}” frame: {reason}
ProtocolMismatch Broker speaks IPC protocol {actual}, this worker {expected}.
MessageTypeMissing No IPC message type is registered for {messageClass}.
MessageTagMissing IPC message {messageClass} has no #[IpcMessage] attribute.
MessageTagDuplicated IPC tag “{tag}” is declared by both {firstClass} and {secondClass}.

Thrown as WorkerException.

Reason Message What to do
Unknown No worker “{workerId}”; stewart status lists the workers.
ShuttingDown Stewart is shutting down, so worker {workerId} is not restarted.

Thrown as StoreSetupException.

Reason Message What to do
DsnInvalid Store URL is invalid ({length} characters); expected a URL like “redis://host:6379/0”.
SchemeUnsupported No installed store backend handles “{scheme}://”; installed schemes: {supported}.
UnknownPeerApp No automation has ID “{appId}”, so its store cannot be opened.
PrefixInvalid Store prefix “{prefix}” is invalid; expected a letter or digit, then up to 63 letters, digits, “.”, “_” or “-”.

Thrown as JsonShapeException.

Reason Message What to do
WrongType “{key}” is {actualType}; expected {expected}.
Missing “{key}” is missing; expected {expected}.
UnexpectedValue “{key}” is {value}; expected {expected}.
InstantInvalid “{key}” is invalid: {cause}
ObjectRefused “{key}” was refused: {cause}

Thrown as HarnessException.

Reason Message What to do
AlreadyStarted The harness already runs {class}; use one harness per app.
AutomationMissing {class} has no #[Automation] attribute, so it is not an app.
NotStarted No app is running; call startApp() first.
OptionMissing {class}::__construct() needs option “{option}”; pass it to startApp().
OptionUnknown Option “{option}” matches no parameter of {class}::__construct().
ParameterUnresolvable {class}::__construct() takes ${parameter} as {type}, which the harness has no fake for; pass one with provideService().