getredash/redash · error

User not found.

Error message

User not found.

What it means

Raised by PermissionResource.post in redash/handlers/permissions.py when User.get_by_id_and_org raises NoResultFound for the supplied user_id — i.e. no user with that id exists in the current organization. The grant cannot proceed because the grantee must be a real org member.

Source

Thrown at redash/handlers/permissions.py:52

        return result

    def post(self, object_type, object_id):
        model = get_model_from_type(object_type)
        obj = get_object_or_404(model.get_by_id_and_org, object_id, self.current_org)

        require_admin_or_owner(obj.user_id)

        req = request.get_json(True)

        access_type = req["access_type"]

        if access_type not in ACCESS_TYPES:
            abort(400, message="Unknown access type.")

        try:
            grantee = User.get_by_id_and_org(req["user_id"], self.current_org)
        except NoResultFound:
            abort(400, message="User not found.")

        permission = AccessPermission.grant(obj, access_type, grantee, self.current_user)
        db.session.commit()

        self.record_event(
            {
                "action": "grant_permission",
                "object_id": object_id,
                "object_type": object_type,
                "grantee": grantee.id,
                "access_type": access_type,
            }
        )

        return permission.to_dict()

    def delete(self, object_type, object_id):
        model = get_model_from_type(object_type)

View on GitHub (pinned to ca79fe988d)

Solutions

  1. Verify the user exists in the same org: GET /api/users and match by id or email.
  2. Refresh user ids at run time instead of caching them; look up by email if ids are unstable.
  3. Handle the 400 by skipping or re-resolving the user in automation scripts.

Example fix

# before
client.post(f'/api/queries/{qid}/permissions', json={'user_id': 12345, 'access_type': 'modify'})

# after
users = {u['email']: u['id'] for u in client.get('/api/users')['results']}
client.post(f'/api/queries/{qid}/permissions', json={'user_id': users['teammate@corp.com'], 'access_type': 'modify'})
Defensive patterns

Strategy: validation

Validate before calling

org_user_ids = {u['id'] for u in client.get('/api/users')['results']}
if user_id not in org_user_ids:
    resolve_or_skip(user_id)

Try / catch

try:
    client.post(perm_url, json=payload)
except HTTPError as e:
    if e.response.status_code == 400 and 'User not found' in e.response.text:
        remove_user_from_grant_list(user_id)
    else:
        raise

Prevention

When it happens

Trigger: POST /api/<object>/<id>/permissions with a user_id that is deleted, belongs to a different org, or is a plain typo/nonexistent id.

Common situations: Stale user ids cached from before users were removed; multi-org deployments where the id exists but in another org; scripts using global ids instead of org-scoped ids.

Related errors


AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28). Data as JSON: /api/errors/dc855d749dd388e6. Report an issue: GitHub.