Troubleshooting¶
This guide helps you diagnose and resolve common issues when using pyvider.cty.
Quick Lookup Index¶
Errors: - CtyValidationError - Data doesn't match schema - CtyAttributeValidationError - Object attribute validation failed - CtyListValidationError - List validation failed - CtyMapValidationError - Map validation failed - CtySetValidationError - Set validation failed - CtyTupleValidationError - Tuple validation failed - CtyTypeMismatchError - Wrong data type - CtyConversionError - Type conversion failed - CtyTypeParseError - Type string parsing failed - SerializationError - MessagePack serialization failed - DeserializationError - MessagePack deserialization failed - CtyFunctionError - Built-in function error
Common Scenarios: - Missing Required Attributes - Type Conversion Issues - Null vs Missing Attributes - Accessing Null Values - Recursion Depth Exceeded
Resources: - Debugging Tips - Performance Troubleshooting - Getting Help
Exception Hierarchy¶
Understanding the exception hierarchy helps you catch and handle errors appropriately:
CtyError (base exception)
│
├── CtyValidationError
│ ├── CtyTypeMismatchError
│ ├── CtyTypeValidationError
│ ├── CtyAttributeValidationError
│ ├── CtyListValidationError
│ ├── CtyMapValidationError
│ ├── CtySetValidationError
│ ├── CtyTupleValidationError
│ ├── CtyStringValidationError
│ ├── CtyNumberValidationError
│ ├── CtyBoolValidationError
│ └── CtyCollectionValidationError
│
├── CtyConversionError
│ ├── CtyTypeConversionError
│ └── CtyTypeParseError
│
├── CtyFunctionError
│
└── EncodingError
├── SerializationError
│ ├── JsonEncodingError
│ └── MsgPackEncodingError
├── DeserializationError
├── WireFormatError
├── DynamicValueError
├── InvalidTypeError
├── AttributePathError
└── TransformationError
Import Path: All exceptions can be imported from pyvider.cty.exceptions
from pyvider.cty.exceptions import (
CtyValidationError,
CtyConversionError,
SerializationError,
# ... and others
)
Catching Exceptions:
from pyvider.cty.exceptions import CtyValidationError, CtyTypeMismatchError
try:
value = schema.validate(data)
except CtyTypeMismatchError as e:
# Handle specific type mismatch
print(f"Type mismatch: {e}")
except CtyValidationError as e:
# Handle all other validation errors
print(f"Validation error: {e}")
Exception Reference¶
Validation Errors¶
CtyValidationError¶
Description: Base exception raised when data doesn't conform to a type schema.
Common Causes: - Wrong data type (e.g., string instead of number) - Missing required attributes in objects - Invalid collection elements - Data structure doesn't match schema
Example:
from pyvider.cty import CtyObject, CtyString, CtyNumber
user_type = CtyObject(
attribute_types={"name": CtyString(), "age": CtyNumber()}
)
# This will raise CtyValidationError - missing 'age' attribute
try:
user = user_type.validate({"name": "Alice"})
except CtyValidationError as e:
print(f"Validation failed: {e}")
# Error message will indicate which attribute is missing
How to Fix: - Read the error message carefully - it includes the path to the invalid field - Verify your data structure matches the schema exactly - Check for typos in attribute names - Ensure all required fields are present
CtyAttributeValidationError¶
Description: Raised when an object attribute fails validation.
Common Causes: - Missing required attributes - Extra attributes not defined in schema - Attribute value doesn't match its type
Example:
from pyvider.cty import CtyObject, CtyString
person_type = CtyObject(attribute_types={"name": CtyString()})
# This will raise CtyAttributeValidationError - 'age' not in schema
try:
person = person_type.validate({"name": "Bob", "age": 30})
except CtyAttributeValidationError as e:
print(f"Attribute error: {e}")
How to Fix:
- Use optional_attributes parameter for optional fields
- Remove extra attributes from data or add them to the schema
- Verify attribute types match the schema
CtyListValidationError¶
Description: Raised when list validation fails.
Common Causes: - Element doesn't match the list's element type - Non-list value passed to list type - Heterogeneous elements in a homogeneous list
Example:
from pyvider.cty import CtyList, CtyString
tags_type = CtyList(element_type=CtyString())
# This will raise CtyListValidationError - contains number
try:
tags = tags_type.validate(["tag1", "tag2", 123])
except CtyListValidationError as e:
print(f"List validation failed: {e}")
How to Fix:
- Ensure all elements match the declared element type
- Check for type mismatches in the list
- Use CtyDynamic if you need heterogeneous lists
CtyMapValidationError¶
Description: Raised when map validation fails.
Common Causes: - Value doesn't match the map's element type - Non-string keys - Non-dict value passed to map type
Example:
from pyvider.cty import CtyMap, CtyNumber
config_type = CtyMap(element_type=CtyNumber())
# This will raise CtyMapValidationError - "three" is not a number
try:
config = config_type.validate({"one": 1, "two": 2, "three": "3"})
except CtyMapValidationError as e:
print(f"Map validation failed: {e}")
How to Fix: - Ensure all values match the declared element type - Verify all keys are strings - Check the data structure is a dictionary
CtySetValidationError¶
Description: Raised when set validation fails.
Common Causes: - Element doesn't match the set's element type - Duplicate elements in input - Unhashable elements
Example:
from pyvider.cty import CtySet, CtyString
unique_tags_type = CtySet(element_type=CtyString())
# This will raise CtySetValidationError - contains number
try:
tags = unique_tags_type.validate({"tag1", "tag2", 123})
except CtySetValidationError as e:
print(f"Set validation failed: {e}")
How to Fix: - Ensure all elements match the declared element type - Remove duplicates if present - Verify elements are hashable
CtyTupleValidationError¶
Description: Raised when tuple validation fails.
Common Causes: - Wrong number of elements - Element at specific position doesn't match expected type - Non-sequence value passed to tuple type
Example:
from pyvider.cty import CtyTuple, CtyString, CtyNumber
point_type = CtyTuple(element_types=[CtyString(), CtyNumber(), CtyNumber()])
# This will raise CtyTupleValidationError - wrong number of elements
try:
point = point_type.validate(["origin", 0]) # Missing third element
except CtyTupleValidationError as e:
print(f"Tuple validation failed: {e}")
How to Fix: - Ensure exactly the right number of elements - Verify each element matches its positional type - Check element order matches the schema
CtyTypeMismatchError¶
Description: Raised when value type doesn't match expected type.
Common Causes: - Passing completely wrong type (e.g., dict instead of list) - Type confusion in nested structures
Example:
from pyvider.cty import CtyString
string_type = CtyString()
# This will raise CtyTypeMismatchError
try:
value = string_type.validate(123) # Number instead of string
except CtyTypeMismatchError as e:
print(f"Type mismatch: {e}")
How to Fix: - Verify the data type matches the schema - Check for type confusion (list vs dict, string vs number) - Use type conversion if appropriate
Conversion Errors¶
CtyConversionError¶
Description: Base exception for type conversion failures.
Common Causes: - Attempting to convert between incompatible types - Invalid string format when converting to number - Conversion would lose data or precision
Example:
from pyvider.cty import CtyString, CtyNumber, convert
string_val = CtyString().validate("not-a-number")
# This will raise CtyConversionError
try:
number_val = convert(string_val, CtyNumber())
except CtyConversionError as e:
print(f"Conversion failed: {e}")
How to Fix:
- Check if the conversion is logically valid
- Verify string format when converting to numbers
- Use validation instead of conversion when appropriate
- Consider using CtyDynamic for unknown types
CtyTypeParseError¶
Description: Raised when parsing a type string fails.
Common Causes: - Invalid Terraform type string syntax - Unsupported type in string - Malformed type expression
Example:
from pyvider.cty import parse_tf_type_to_ctytype
# This will raise CtyTypeParseError - invalid syntax
try:
parsed_type = parse_tf_type_to_ctytype("invalid[type{syntax")
except CtyTypeParseError as e:
print(f"Parse error: {e}")
How to Fix: - Verify the type string syntax is correct - Check for matching brackets and braces - Refer to Terraform type syntax documentation - Use explicit type construction instead of parsing
Serialization Errors¶
SerializationError¶
Description: Raised when serializing a value to MessagePack fails.
Common Causes: - Unsupported data type in value - Circular references - Capsule types without proper serialization support
Example:
from pyvider.cty import CtyObject, CtyString
from pyvider.cty.codec import cty_to_msgpack
from pyvider.cty.exceptions import SerializationError
schema = CtyObject(attribute_types={"key": CtyString()})
value = schema.validate({"key": "value"})
# Normally this works, but can fail with incompatible data
try:
msgpack_bytes = cty_to_msgpack(value, schema)
except SerializationError as e:
print(f"Serialization failed: {e}")
How to Fix: - Ensure all data types are serializable - Check for circular references in capsule types - Verify capsule types implement proper serialization
DeserializationError¶
Description: Raised when deserializing MessagePack data fails.
Common Causes: - Corrupted MessagePack data - Schema mismatch between serialization and deserialization - Invalid MessagePack format
Example:
from pyvider.cty import CtyObject, CtyString
from pyvider.cty.codec import cty_from_msgpack
from pyvider.cty.exceptions import DeserializationError
schema = CtyObject(attribute_types={"key": CtyString()})
# This will raise DeserializationError - invalid data
try:
value = cty_from_msgpack(b"invalid msgpack data", schema)
except DeserializationError as e:
print(f"Deserialization failed: {e}")
How to Fix: - Verify the MessagePack data is not corrupted - Ensure the same schema is used for serialization and deserialization - Check data was actually serialized with cty_to_msgpack
Function Errors¶
CtyFunctionError¶
Description: Raised when a built-in function fails.
Common Causes: - Invalid arguments to function - Null or unknown values where concrete values expected - Type mismatch in function parameters
Example:
from pyvider.cty import CtyString
from pyvider.cty.functions import upper
from pyvider.cty.exceptions import CtyFunctionError
# This will raise CtyFunctionError - null value
try:
null_val = CtyString().validate(None)
result = upper(null_val)
except CtyFunctionError as e:
print(f"Function error: {e}")
How to Fix: - Check function documentation for argument requirements - Verify values are not null or unknown unless function supports it - Ensure argument types match function expectations
Common Scenarios¶
Scenario 1: Missing Required Attributes¶
Problem:
from pyvider.cty import CtyObject, CtyString, CtyNumber
schema = CtyObject(
attribute_types={
"name": CtyString(),
"age": CtyNumber(),
}
)
# Error: missing 'age'
data = {"name": "Alice"}
value = schema.validate(data) # Raises CtyValidationError
Solution:
# Option 1: Make 'age' optional
schema = CtyObject(
attribute_types={"name": CtyString(), "age": CtyNumber()},
optional_attributes={"age"}
)
value = schema.validate({"name": "Alice"}) # Works!
# Option 2: Provide all required fields
value = schema.validate({"name": "Alice", "age": 30}) # Works!
Scenario 2: Type Conversion Issues¶
Problem:
from pyvider.cty import CtyNumber
number_type = CtyNumber()
value = number_type.validate("123") # Raises CtyTypeMismatchError
Solution:
# Option 1: Use conversion
from pyvider.cty import CtyString, convert
string_val = CtyString().validate("123")
number_val = convert(string_val, CtyNumber()) # Works!
# Option 2: Provide correct type
value = number_type.validate(123) # Works!
Scenario 3: Null vs Missing Attributes¶
Problem:
from pyvider.cty import CtyObject, CtyString, CtyValue
schema = CtyObject(
attribute_types={"name": CtyString(), "nickname": CtyString()},
optional_attributes={"nickname"}
)
# What's the difference between these?
data1 = {"name": "Alice"} # nickname is missing
data2 = {"name": "Alice", "nickname": None} # nickname is explicitly null
Solution:
# Missing optional attribute becomes null automatically
value1 = schema.validate(data1)
print(value1["nickname"].is_null) # True
# Explicit None also becomes null
value2 = schema.validate(data2)
print(value2["nickname"].is_null) # True
# Both are equivalent in cty
Scenario 4: Accessing Null Values¶
Problem:
from pyvider.cty import CtyObject, CtyString
schema = CtyObject(
attribute_types={"name": CtyString()},
optional_attributes={"name"}
)
value = schema.validate({})
name = value["name"].raw_value # Raises error - can't get raw_value of null
Solution:
# Check for null before accessing
value = schema.validate({})
if value["name"].is_null:
print("Name is not provided")
else:
print(f"Name: {value['name'].raw_value}")
Scenario 5: Recursion Depth Exceeded¶
Problem:
# Creating extremely deep nested structure
deep_data = {"level": {}}
current = deep_data["level"]
for i in range(1000):
current["level"] = {}
current = current["level"]
# This may raise recursion depth error
Solution:
from pyvider.cty.context import MAX_VALIDATION_DEPTH
# The default limit is 500 levels
# If you need deeper structures, consider:
# 1. Flattening your data structure
# 2. Using references instead of deep nesting
# 3. Adjusting MAX_VALIDATION_DEPTH (with caution)
Debugging Tips¶
1. Enable Detailed Error Messages¶
Validation errors include the full path to the problematic field:
try:
value = complex_schema.validate(data)
except CtyValidationError as e:
print(f"Error at: {e}")
# Example output: "at path.users[2].address.city: expected CtyString, got int"
2. Inspect Raw Values¶
When debugging, inspect the raw Python values:
from pyvider.cty import CtyObject, CtyString
schema = CtyObject(attribute_types={"name": CtyString()})
data = {"name": "Alice"}
print(f"Raw data: {repr(data)}")
value = schema.validate(data)
print(f"Validated value: {value}")
print(f"Name raw value: {value['name'].raw_value}")
3. Use a Debugger¶
Set breakpoints in your validation code:
import pdb
try:
value = schema.validate(data)
except CtyValidationError as e:
pdb.set_trace() # Drop into debugger to inspect state
4. Simplify the Problem¶
When dealing with complex structures, test incrementally:
# Instead of validating everything at once
full_data = {"user": {"profile": {"settings": {...}}}}
# Test each level separately
user_data = {"profile": {...}}
profile_data = {"settings": {...}}
# Validate from inside out
settings_value = settings_schema.validate(settings_data)
profile_value = profile_schema.validate(profile_data)
user_value = user_schema.validate(user_data)
5. Check Type Compatibility¶
Use the type system to verify compatibility:
from pyvider.cty import CtyString, CtyNumber, unify
# Check if types can be unified
try:
unified_type = unify([CtyString(), CtyNumber()])
print(f"Unified to: {unified_type}")
except Exception as e:
print(f"Types are incompatible: {e}")
6. Validate Incrementally¶
For complex nested structures, validate step by step:
# Bad: One massive validation that's hard to debug
full_config = {...deeply nested...}
config_value = config_schema.validate(full_config)
# Good: Validate subsections
db_value = db_schema.validate(config["database"])
api_value = api_schema.validate(config["api"])
full_value = full_schema.validate({"database": db_value, "api": api_value})
Performance Troubleshooting¶
Large Data Structures¶
Problem: Validation is slow for large datasets.
Solutions:
- Cache schema objects - don't recreate types repeatedly
- Validate once, reuse the validated CtyValue
- Consider batching for very large datasets
- Profile to identify bottlenecks
# Bad: Creating schema inside loop
for item in large_dataset:
schema = CtyObject(attribute_types={"field": CtyString()}) # Recreated every time!
value = schema.validate(item)
# Good: Create schema once
schema = CtyObject(attribute_types={"field": CtyString()})
for item in large_dataset:
value = schema.validate(item)
Deep Nesting¶
Problem: Deeply nested structures cause performance issues.
Solutions: - Flatten data structures where possible - Use references instead of deep nesting - Consider alternative data modeling
Getting Help¶
If you're still stuck after consulting this guide:
- Check the documentation: Review the User Guide and API Reference
- Review examples: Look at the Examples for similar use cases
- Search issues: Check GitHub Issues for similar problems
- Ask for help: Open a new issue with a minimal reproducible example
When reporting issues, include: - Complete error message and stack trace - Minimal code example that reproduces the issue - Your Python version and pyvider.cty version - What you expected vs what actually happened