fullstackhero/dotnet-starter-kit · warning · ForbiddenException

not allowed to change this file's visibility

Error message

not allowed to change this file's visibility

What it means

The resolved access policy's CanChangeVisibilityAsync returned false for (file, userId), so the handler throws ForbiddenException. The policy receives FileAccessContext (owner type/id, creator, current visibility) and encodes business rules such as 'only the creator or an admin may flip visibility'.

Solutions

  1. Confirm the acting user actually owns/created the file or holds the admin/owner role the policy requires.
  2. Review the OwnerType policy implementation (CanChangeVisibilityAsync) to see which condition failed and align the request with it.
  3. If the rule is wrong, change the policy implementation — do not bypass it in the handler.
  4. Check that ICurrentUser resolves the intended user (token/impersonation) rather than a different identity.

Example fix

// before
await client.ChangeVisibilityAsync(fileOwnedBySomeoneElseId, Visibility.Public); // 403
// after
var file = await client.GetFileAsync(id);
if (file.CreatedByUserId == currentUserId) await client.ChangeVisibilityAsync(id, Visibility.Public);
Defensive patterns

Strategy: try-catch

Validate before calling

var file = await client.GetFileAsync(id);
if (file.CreatedByUserId != currentUserId && !userIsAdmin) throw new UnauthorizedAccessException("Only the creator or an admin may change visibility.");

Try / catch

catch (ForbiddenException e) when (e.Message.Contains("visibility")) {
    notify("You do not have permission to change this file's visibility.");
}

Prevention

When it happens

Trigger: Authenticated user calls change-visibility on a file they are not permitted to manage: not the creator, not an owner/admin for the OwnerType, or the policy's role/permission check fails for that user.

Common situations: User attempts to publish a teammate's file; a normal tenant user tries to make a file public in a deployment where only admins may; API client calls with a user token that lacks the file-management permission; owner-type policy was tightened and old UI still allows the action.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15). Data as JSON: /api/errors/673d941eaf3f5630. Report an issue: GitHub.

Appendix: source

Thrown at src/Modules/Files/Modules.Files/Features/v1/ChangeVisibility/ChangeFileVisibilityCommandHandler.cs:46

        {
            throw new CustomException(
                $"Unknown visibility value '{cmd.Visibility}'.",
                errors: null,
                System.Net.HttpStatusCode.BadRequest);
        }

        var f = await db.FileAssets
            .FirstOrDefaultAsync(x => x.Id == cmd.FileAssetId, cancellationToken)
            .ConfigureAwait(false)
            ?? throw new NotFoundException("file not found");

        var userId = currentUser.GetUserId().ToString();
        var policy = policies.Resolve(f.OwnerType)
            ?? throw new ForbiddenException("no policy");
        var ctx = new FileAccessContext(f.Id, f.OwnerType, f.OwnerId, f.CreatedByUserId, (int)f.Visibility);
        if (!await policy.CanChangeVisibilityAsync(ctx, userId, cancellationToken).ConfigureAwait(false))
        {
            throw new ForbiddenException("not allowed to change this file's visibility");
        }

        f.ChangeVisibility(cmd.Visibility);
        await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

        var publicUrl = f.Visibility == Visibility.Public
            ? storage.BuildPublicUrl(f.StorageKey)
            : null;
        return FileAssetMapper.ToDto(f, publicUrl);
    }
}

View on GitHub (pinned to 3f2959e683)