Custom Data Patterns
This skill identifies common anti-patterns in how Canvas plugins use Custom Data (CustomModels and AttributeHubs) and provides corrections. These patterns have been observed in real customer plugins.
When to Use This Skill
Invoke this skill proactively as soon as Custom Data is involved — don't wait for a review phase. Use it when:
- The plugin spec calls for persistent data storage (CustomModels or AttributeHubs)
- You are about to write or edit model definitions that subclass
CustomModel - You are about to write or edit code that uses
AttributeHub - You are adding relationships (ForeignKey, OneToOneField, ManyToManyField) to SDK models
- You are setting up the plugin directory structure and it will include CustomModels
- Reviewing existing plugin code that uses Custom Data
Quick Reference
Reference the custom_data_context.txt file for detailed anti-patterns with BAD/GOOD examples.
Custom-data models are keyed on
dbid, notid. Any query that references"id"on aCustomModel—Count("id"),order_by("id"),values("id"),F("id")— raisesFieldError: Cannot resolve keyword 'id' into field. Usedbid(the primary key on the SDK base model). Tests that mock the queryset (patch(...objects...)) never resolve the real field name, so this bug passes CI and 500s against a live DB. See the database-performance skill (§"Canvas Execution Limits") for detection and the write-amplification/idempotency patterns that also apply to custom-data-backed sync.