You're encountering this error when creating new users:
Error running hook URI: pg-functions://postgres/public/custom_access_token_hook
The custom_access_token_hook function that injects user roles into JWT tokens is either:
- Missing proper permissions for Supabase Auth to execute it
- Has an error in its implementation
- Needs proper error handling
I've created a comprehensive fix with backup/restore capabilities to protect your English course data.
Before any database reset, backup your course data:
npm run backup-courseThis will create supabase/backup-courses.json with all your courses, lessons, exercises, exams, and questions.
You have two options:
# Push the new migration to fix the JWT hook
supabase db push
# Restart Supabase services to reload the hook
supabase stop
supabase start# Reset the database (this applies all migrations including the fix)
supabase db reset
# Restore your English course
npm run restore-courseTry creating a new user through your signup form. The error should be gone.
The new migration (20260214010000_fix_jwt_hook_permissions.sql) does the following:
- Drops and recreates the
custom_access_token_hookfunction with proper settings - Adds error handling so auth doesn't break if the hook fails
- Grants explicit permissions to
supabase_auth_adminandservice_role - Sets proper ownership to the
postgresuser - Defaults to 'student' role if no role is found (instead of returning null)
-- Before: No error handling
CREATE OR REPLACE FUNCTION public.custom_access_token_hook(event jsonb)
...
-- After: With error handling and default role
CREATE OR REPLACE FUNCTION public.custom_access_token_hook(event jsonb)
RETURNS jsonb
...
EXCEPTION
WHEN OTHERS THEN
RAISE WARNING 'Error in custom_access_token_hook: %', SQLERRM;
RETURN event; -- Don't break auth if hook fails
END;After applying the fix, verify it's working:
-
Check the function exists:
supabase db diff
-
Create a test user through your signup form
-
Check the user's JWT includes the
user_roleclaim:- Open browser DevTools
- Go to Application > Local Storage
- Find the Supabase session
- Decode the JWT at jwt.io to see claims
I've created two helper scripts:
- Exports all courses with full nested data
- Saves to
supabase/backup-courses.json - Run with:
npm run backup-course
- Imports from
supabase/backup-courses.json - Recreates courses with new IDs
- Maintains relationships between courses, lessons, exams, etc.
- Run with:
npm run restore-course
If the error persists after applying the fix:
-
Check Supabase logs:
supabase logs --local
-
Check the auth service logs specifically:
docker logs supabase_auth_lms-front
-
Verify the config.toml has the hook enabled (lines 263-265):
[auth.hook.custom_access_token] enabled = true uri = "pg-functions://postgres/public/custom_access_token_hook"
-
Make sure the
user_rolestable has proper data:- New users should get 'student' role automatically via
handle_new_user()trigger
- New users should get 'student' role automatically via
- Your English course data is NOT in the seed files, so backup is essential before any reset
- The JWT hook runs during every authentication to add the
user_roleclaim - The hook must be fast and reliable or it will block authentication
- The new version includes error handling to prevent auth from breaking