🧱 Суть

Ошибка:

406 Not Acceptable

в Supabase часто означает не проблему с форматом данных, а то, что PostgREST не смог вернуть результат из-за ограничений доступа.

Обычно причина:

  • включён RLS;
  • нет подходящей политики;
  • пользователь не имеет права читать нужную строку.

📦 Проблема

Например, есть запрос:

const { data, error } = await supabase
  .from('user_profiles')
  .select('*')
  .eq('id', user.id)
  .single();

Таблица существует.
Строка существует.

Но Supabase возвращает:

406 Not Acceptable

Почему?
Потому что RLS скрывает эту строку от текущего пользователя.
Для Supabase это выглядит так: “Я не могу показать эту запись этому пользователю”.

Почему возникает именно 406

Метод:

.single()

ожидает получить ровно одну строку.

Но из-за RLS запрос фактически превращается в:

0 доступных строк

То есть:

Ожидали:
[user_profile]
 
Получили:
[]

Из-за этого PostgREST не может вернуть ожидаемый одиночный объект.

✅ Решение

Нужно добавить политику доступа.
Например:

CREATE POLICY "Users can select their own profile"
ON public.user_profiles
FOR SELECT
USING (auth.uid() = id);

Теперь:

  • пользователь делает запрос;
  • Supabase получает его auth.uid();
  • сравнивает с id строки;
  • если совпадает – разрешает доступ.

💻 Код

Проверка текущего пользователя:

const {
  data: { user }
} = await supabase.auth.getUser();

Получение профиля:

const { data, error } = await supabase
  .from('user_profiles')
  .select('*')
  .eq('id', user.id)
  .single();

Политика:

CREATE POLICY "Users can read own profile"
ON user_profiles
FOR SELECT
USING (
  auth.uid() = id
);

Проверка при ошибке

Если получаешь 406, проверь:

  1. Таблица существует:
select * from user_profiles;
  1. RLS включён:
ALTER TABLE user_profiles ENABLE ROW LEVEL SECURITY;
  1. Есть политика SELECT.
  2. Пользователь авторизован.
  3. JWT содержит актуальную сессию.

🎯 Вывод

  • 406 в Supabase часто означает проблему с доступом, а не ошибку запроса.
  • Главный подозреваемый – RLS.
  • Если используешь .single(), отсутствие доступа к строке превращается в 406.
  • Исправляется созданием правильной политики.

🔗 Связано