Troubleshooting
This guide covers the exception classes in RevitPy and common issues you may encounter.
API Exceptions
These exceptions are defined in revitpy.api.exceptions.
RevitAPIError
The base exception for all RevitPy API errors.
from revitpy.api.exceptions import RevitAPIError
try:
api.open_document("nonexistent.rvt")
except RevitAPIError as e:
print(e) # Error message
print(e.cause) # Original exception, if any
Attributes:
cause– The underlying exception, orNone.
ConnectionError
Raised when RevitPy cannot connect to the Revit application or when an operation is attempted without a connection.
from revitpy.api.exceptions import ConnectionError
Common causes:
- Calling
api.elementsorapi.transaction()before callingapi.connect(). - Calling
api.connect()without providing a Revit application object. - The Revit application is not running or not accessible.
Solutions:
- Ensure
api.connect(revit_application)is called before any operations. - Verify that the Revit application object is valid and accessible.
- Use
api.is_connectedto check the connection status before operations.
ElementNotFoundError
Raised when an element cannot be found by ID or when a parameter does not exist on an element.
from revitpy.api.exceptions import ElementNotFoundError
Attributes:
element_id– The ID that was searched for.element_type– The type name, if applicable.cause– The underlying exception.
Common causes:
- Looking up an element by an ID that does not exist in the document.
- Accessing a parameter name that does not exist on the element.
- The element was deleted between the time its ID was obtained and the lookup.
Solutions:
- Use
api.get_element_by_id()which returnsNonefor missing elements instead of raising. - Use
first_or_default()instead offirst()when the query may return no results. - Verify parameter names match exactly (they are case-sensitive).
TransactionError
Raised during transaction operations (start, commit, rollback).
from revitpy.api.exceptions import TransactionError
Attributes:
transaction_name– Name of the transaction.cause– The underlying exception.
Common causes:
- Attempting to start a transaction that has already been started.
- Committing a transaction that is not in the
STARTEDstate. - An operation failing inside a transaction, triggering a rollback.
Solutions:
- Use transactions as context managers (
with api.transaction(...)) to ensure proper start/commit/rollback handling. - Check
transaction.statusbefore callingcommit()orrollback()manually. - Use
retry_transaction()for operations that may fail transiently.
ValidationError
Raised when a parameter value fails validation.
from revitpy.api.exceptions import ValidationError
Attributes:
field– The field/parameter name.value– The invalid value.cause– The underlying exception.
Common causes:
- Setting a parameter to a value that cannot be converted to the expected type (e.g., setting a numeric parameter to a non-numeric string).
- Setting a parameter that fails Revit-side validation.
Solutions:
- Verify the expected type before setting parameter values. Use
ParameterValue.storage_typeto check. - Ensure values match the parameter’s storage type (
String,Double,Integer).
PermissionError
Raised when attempting a disallowed operation, such as writing to a read-only parameter.
from revitpy.api.exceptions import PermissionError
Attributes:
operation– The operation that was denied.
Solutions:
- Check
ParameterValue.is_read_onlybefore attempting to write. - Use
ElementProperty.read_onlywhen defining custom property descriptors.
ModelError
Raised when the model is in an invalid state, such as failing to create or open a document.
from revitpy.api.exceptions import ModelError
Common causes:
open_document()returnsNonefrom Revit.create_document()returnsNone.
Solutions:
- Verify the file path exists and is accessible.
- Ensure the template path is valid for
create_document().
ORM Exceptions
These exceptions are defined in revitpy.orm.exceptions. They all inherit from ORMException.
ORMException
Base exception for all ORM errors.
Attributes:
operation– The ORM operation that failed (e.g.,"save_changes","query","get_by_id").entity_type– The entity type name, if applicable.entity_id– The entity ID, if applicable.cause– The underlying exception.
QueryError
Raised when a query operation fails.
Attributes:
query_expression– String representation of the query.query_operation– The operation that failed (e.g.,"first","single").element_count– Number of elements found (useful forsingle()errors).
Common causes:
- Calling
first()on an empty result set. - Calling
single()when zero or more than one element matches. - An error in a predicate function.
Solutions:
- Use
first_or_default()orsingle_or_default()when results may be empty. - Verify predicates do not raise exceptions by testing them independently.
RelationshipError
Raised when relationship loading or configuration fails.
Attributes:
relationship_name– The relationship that failed.source_entity– The source entity.target_entity– The target entity.
Common causes:
- Calling
load_relationship()without a configured relationship manager.
Solutions:
- Call
context.configure_relationship()before loading relationships.
CacheError
Raised when cache operations fail.
Attributes:
cache_key– The cache key involved.cache_operation– The cache operation that failed.
ChangeTrackingError
Raised when change tracking operations fail.
Attributes:
entity– The entity involved.property_name– The property name, if applicable.tracking_operation– The operation that failed.
LazyLoadingError
Raised when lazy loading of a property or relationship fails.
Attributes:
property_name– The property being loaded.entity– The entity being loaded.
AsyncOperationError
Raised when an async ORM operation fails.
Attributes:
async_operation– The async operation name.task_id– The task ID, if applicable.
BatchOperationError
Raised when a batch operation partially or fully fails.
Attributes:
batch_size– Total batch size.failed_operations– List of failed operation details.successful_operations– Number of operations that succeeded.
ValidationError (ORM)
Raised when entity validation fails in the ORM layer.
Attributes:
validation_errors– Dictionary of field names to lists of error messages.entity– The entity that failed validation.
ConcurrencyError
Raised when concurrent modifications conflict.
Attributes:
entity– The entity with conflicts.conflicting_changes– Dictionary of conflicting property changes.
TransactionError (ORM)
Raised when ORM transaction operations fail.
Attributes:
transaction_id– The transaction ID.transaction_state– The transaction state at the time of failure.nested_level– The nesting level.
Common Issues and Solutions
“No active document” error
Problem: You see ConnectionError: No active document when calling api.elements, api.query(), or api.transaction().
Solution: Open or create a document first:
api.connect(revit_application)
api.open_document("path/to/project.rvt")
# Now api.active_document is set
“RevitContext has been disposed” error
Problem: You see ORMException: RevitContext has been disposed when calling context methods.
Solution: The context was used after exiting a with block or after calling dispose(). Create a new context:
# Wrong
with RevitContext(provider) as ctx:
pass
ctx.query() # Error: context is disposed
# Right
with RevitContext(provider) as ctx:
ctx.query() # Use inside the block
Circular dependency in DI container
Problem: RuntimeError: Circular dependency detected: A -> B -> A
Solution: Refactor to break the cycle. Options include:
- Use a factory function that resolves one dependency lazily.
- Use
register_singletonwith a pre-created instance for one of the services. - Restructure the dependency graph.
“Service X is not registered” error
Problem: ValueError: Service MyService is not registered when calling container.get_service().
Solution: Register the service before resolving it:
container.register_singleton(MyService, instance=my_instance)
service = container.get_service(MyService)
Event handler disabled after errors
Problem: An event handler stops executing after repeated failures.
Solution: The @event_handler decorator disables a handler after max_errors failures (default 10). Fix the underlying error, then either:
- Increase
max_errorsin the decorator. - Re-register the handler.
- Use
@retry_on_errorto add retry logic.
Slow queries
Problem: Queries take a long time to execute.
Solution:
- Add more specific filters to reduce the result set.
- Use
take()to limit the number of results. - Enable caching in the ORM context (
CachePolicy.MEMORYorCachePolicy.AGGRESSIVE). - For large datasets, use the ORM
as_streaming()method for batch processing. - Check
context.cache_statisticsto verify cache hit rates.
Transaction timeout
Problem: A transaction times out before completing.
Solution:
- Increase
timeout_secondsinTransactionOptions. - Break large operations into smaller transactions using
TransactionGroup. - Use batch processing with
AsyncRevit.update_elements_async()for bulk updates.