Debug Knowledge Service
debug-knowledge
Debug the Copilot Knowledge service - investigate sync failures, schema mismatches, and data issues between tenants.
SKILL.md
Full skill instructions
Debug Knowledge Service
You are debugging the Copilot Knowledge service, which exports models from one tenant's WrenAI instance and syncs them to other tenants.
Architecture Overview
┌─────────────────┐ Export ┌──────────────────┐ Sync ┌─────────────────┐
│ Source Tenant │ ───────────► │ KnowledgeItem │ ────────────► │ Target Tenant │
│ (WrenAI + DB) │ │ (hub-backend) │ │ (WrenAI + DB) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
Key services location: hub-backend/app/services/hub/chord_ai/knowledge/
Debugging Setup
Always start by setting up your test environment. Use mise for correct Ruby version:
# Run with: eval "$(mise activate bash)" && bin/rails runner "<code>"
tenant_1 = Hub::Tenant.first
store_1 = tenant_1.stores.first
tenant_2 = Hub::Tenant.second
store_2 = tenant_2.stores.first
user = Hub::User.last
environment = 'staging' # or 'production'
Key Services Reference
1. List Models in WrenAI
See what models exist in a tenant's WrenAI instance:
result = Hub::ChordAI::Knowledge::Models::List.call(
tenant: tenant, store: store, user: user, environment: 'staging'
)
models = result.success? ? result.data : []
models.each { |m| puts "#{m['referenceName']} (#{m['fields']&.count} fields)" }
2. Get Single Model Details
Get full details including fields, calculated fields:
result = Hub::ChordAI::Knowledge::Models::Get.call(
tenant: tenant, store: store, user: user, id: model_id, environment: 'staging'
)
model = result.data
model['fields'].each { |f| puts "#{f['sourceColumnName']} -> #{f['type']}" }
3. List Data Source Tables (Snowflake)
See what tables/columns exist in the actual database:
result = Hub::ChordAI::Knowledge::DataSourceTables.call(
tenant: tenant, store: store, user: user, environment: 'staging'
)
tables = result.data
table = tables.find { |t| t['name'].include?('TABLE_NAME') }
table['columns'].each { |c| puts c['name'] }
4. Check Knowledge Items (Exported Models)
Hub::ChordAI::KnowledgeItem.all.each do |item|
puts "#{item.reference_name} - #{item.item_type} (#{item.assignments.count} assignments)"
end
5. Check Assignments and Sync Status
item = Hub::ChordAI::KnowledgeItem.find(id)
item.assignments.each do |a|
puts "Tenant: #{a.hub_tenant.name}, Status: #{a.sync_status}, Error: #{a.last_error}"
end
Common Debugging Scenarios
Scenario 1: GraphQL Schema Mismatch
Symptom: Error like String cannot represent a non string value or Field "X" is not defined
Investigation:
- Identify which service is failing from the error path (e.g.,
data.fields[0]) - Find the GraphQL mutation in the service file
- Use the wrenai agent to check the actual schema:
Use Task tool with subagent_type=wrenai to find the GraphQL input type definition
in wren-ui/src/apollo/server/schema.ts
- Compare what hub-backend sends vs what schema expects
Common fixes:
- Array of objects → Array of strings (fields: [String!]!)
- Missing required field (id: Int!)
- Extra field not in schema
Scenario 2: Column Not Found in Data Source
Symptom: Error like Column "X" not found in table "Y" in the data Source
Investigation:
- Check if column exists in source tenant's data source:
# Get data source tables
result = Hub::ChordAI::Knowledge::DataSourceTables.call(...)
table = result.data.find { |t| t['name'] == 'TABLE_NAME' }
cols = table['columns'].map { |c| c['name'] }
puts cols.include?('COLUMN_NAME') # Should be true
- Check if model has phantom columns (model fields > data source columns):
# Compare model fields vs data source columns
model_fields = model['fields'].map { |f| f['sourceColumnName'] }
db_columns = table['columns'].map { |c| c['name'] }
phantom = model_fields - db_columns
puts "Phantom columns: #{phantom}" # These exist in model but not DB
- If phantom columns exist, the source model is corrupted/stale
Scenario 3: Model Exists in One Tenant But Not Another
Symptom: Sync fails because model doesn't exist in target
Investigation:
# Compare models between tenants
result_1 = Hub::ChordAI::Knowledge::Models::List.call(tenant: tenant_1, ...)
result_2 = Hub::ChordAI::Knowledge::Models::List.call(tenant: tenant_2, ...)
names_1 = result_1.data.map { |m| m['referenceName'] }
names_2 = result_2.data.map { |m| m['referenceName'] }
only_in_1 = names_1 - names_2
only_in_2 = names_2 - names_1
puts "Only in tenant 1: #{only_in_1}"
puts "Only in tenant 2: #{only_in_2}"
Scenario 4: Field Count Mismatch Between Tenants
Symptom: Same model name but different field counts
Investigation:
model_1 = result_1.data.find { |m| m['referenceName'] == 'MODEL_NAME' }
model_2 = result_2.data.find { |m| m['referenceName'] == 'MODEL_NAME' }
fields_1 = model_1['fields'].map { |f| f['sourceColumnName'] }.sort
fields_2 = model_2['fields'].map { |f| f['sourceColumnName'] }.sort
only_in_1 = fields_1 - fields_2
only_in_2 = fields_2 - fields_1
puts "Fields only in tenant 1: #{only_in_1}"
puts "Fields only in tenant 2: #{only_in_2}"
When to Use WrenAI Agent
Spawn the wrenai agent (via Task tool with subagent_type=wrenai) when you need to:
- Validate GraphQL schema - Find input type definitions in
wren-ui/src/apollo/server/schema.ts - Understand WrenAI internals - How models, fields, relations are stored
- Check GraphQL resolvers - What mutations actually do on the WrenAI side
- Investigate WrenAI-specific errors - Errors originating from WrenAI's validation
Example prompt for wrenai agent:
Find the GraphQL schema definition for UpdateModelMetadataInput and
UpdateColumnMetadataInput in wren-ui/src/apollo/server/schema.ts.
List all fields and their types.
Quick Diagnostic Checklist
When investigating a Knowledge sync failure:
- What's the exact error message?
- Which service is failing? (check stack trace)
- Is it a GraphQL schema issue or data issue?
- Does the model exist in source tenant's WrenAI?
- Does the table exist in target's data source?
- Do all model fields exist in the data source?
- Are there phantom columns in the source model?
- Is this a new model creation or update to existing?
File Locations
| Component | Location |
|---|---|
| Knowledge services | hub-backend/app/services/hub/chord_ai/knowledge/ |
| Models services | hub-backend/app/services/hub/chord_ai/knowledge/models/ |
| Sync logic | hub-backend/app/services/hub/chord_ai/knowledge/sync_model.rb |
| Export logic | hub-backend/app/services/hub/chord_ai/knowledge/export.rb |
| WrenAI GraphQL schema | wrenai/wren-ui/src/apollo/server/schema.ts |
| Project documentation | projects/copilot-knowledge/ |
| Learning notes | learn/hub-backend/wrenai-graphql-integration.md |
