Troubleshooting
Diagnose and fix common Melange issues.
Using melange doctor
melange doctor --db "$DATABASE_URL"Doctor runs six categories of checks against your database:
- Schema File: exists, parses correctly, no cyclic dependencies.
- Migration State:
melange_migrationstable exists, schema is in sync, codegen version matches. - Generated Functions: dispatcher and per-relation functions are present, no orphans from previous schemas.
- Tuples Source:
melange_tuplesview exists with the correct columns. - Data Health: tuple count, types and relations validate against the schema.
- Performance: UNION ALL usage, missing expression indexes on
::textcast columns.
Use --verbose for detailed output (exact checksums, function lists, specific invalid tuples):
melange doctor --verboseSkip performance checks if you only need structural validation:
melange doctor --skip-performanceCommon Errors
“relation melange_tuples does not exist”
The melange_tuples view has not been created, or it was created in a different schema than the one your connection uses.
Fix: create the view. See Creating Your Tuples View.
“function check_permission does not exist”
The migration has not been run, or it was run against a different database or schema.
Fix: run melange migrate --db "$DATABASE_URL".
Permission checks always return false
The tuples view exists but returns no rows for the subject/object/relation being checked.
Debug:
-- Check what tuples exist for the subject
SELECT * FROM melange_tuples WHERE subject_type = 'user' AND subject_id = 'alice';
-- Check what tuples exist for the object
SELECT * FROM melange_tuples WHERE object_type = 'repository' AND object_id = '42';Common causes:
- Relation names in the view don’t match the schema (e.g.,
'is_member'vs'member'). - ID types aren’t cast to text (
user_idvsuser_id::text). - The domain table has no data for the given subject/object.
Permission checks always return true
A wildcard subject (user:*) is granting broader access than intended.
Debug:
SELECT * FROM melange_tuples WHERE subject_id = '*';Check that wildcard rows are scoped to the correct relation and object type.
Slow permission checks
Debug:
EXPLAIN ANALYZE SELECT check_permission('user', '123', 'can_read', 'repository', '456');Look for Seq Scan in the output. Common causes:
- Missing expression indexes on
::textcast columns. Runmelange doctorfor specificCREATE INDEXrecommendations. - Large source tables without appropriate composite indexes.
- Complex schema patterns (deeply nested exclusions or parent chains).
See Scaling for optimization strategies.
Schema validation errors
melange validateCommon causes:
- Syntax errors in the
.fgafile. The error message includes the line number. - Cyclic dependencies in implied-by relationships (e.g.,
define a: banddefine b: a). - References to undefined types or relations.
Migration “schema unchanged” when it shouldn’t be
Melange tracks schema changes via SHA256 checksum. If you’ve updated Melange itself but not the schema, the new codegen may produce different SQL.
Fix: force re-migration:
melange migrate --forceSchema out of sync after updating Melange
melange doctor detects when the codegen version has changed since the last migration.
Fix: run melange migrate --force to regenerate all SQL functions with the current Melange version.
Debugging Techniques
Preview Generated SQL
melange migrate --dry-runOutputs the complete SQL that would be executed. Redirect to a file for inspection:
melange migrate --dry-run > migration.sqlInspect Tuple Data
-- All tuples for a specific object
SELECT * FROM melange_tuples
WHERE object_type = 'repository' AND object_id = '42'
ORDER BY relation, subject_type, subject_id;
-- Count tuples by type
SELECT object_type, relation, count(*)
FROM melange_tuples
GROUP BY object_type, relation
ORDER BY count DESC;Query Plan Analysis
EXPLAIN ANALYZE
SELECT * FROM melange_tuples
WHERE object_type = 'repository' AND object_id = '42'
AND relation = 'can_read' AND subject_type = 'user';Look for:
Seq ScanwithFilter:lines containing::textcasts. This means expression indexes are needed.- High
actual timevalues on individual branches of the UNION ALL.
Check Effective Configuration
melange config show --sourceShows which config file is in use and the effective values after merging defaults, config file, and environment variables.
Getting Help
If you’re stuck, open an issue at github.com/pthm/melange/issues with:
- Your
.fgaschema - The
melange doctor --verboseoutput - The error message or unexpected behavior
- Your Melange version (
melange version)
Next Steps
- CLI Reference: full command documentation and exit codes
- Errors: error types and sentinel values
- Scaling: performance optimization strategies