Jump to content

CONFIRMED: Both Tags AND Parental Ratings Are Broken - Parental Control Tags don't reflect on Music Albums


Recommended Posts

mouth883
Posted

I have the exact same issue as detailed in here 

 

 

After spending an hour trying to get it working, I downloaded the latest version of the server and walked Claude Code through the problem

 

Here's the diagnosis. Would be great to get this fixed. I'm a paying lifetime subscriber... 

 


1. Tag filtering - Looks for tags on the album's ancestors (broken)
2. Parental rating filtering - Looks for ratings on the album's ancestors (broken)
Both use the AncestorIds2 table to find parent folders, but MusicAlbum entities don't have parent folders - they're virtual entities created from song metadata.
COMPLETE FIX FOR BOTH ISSUES
Here's a comprehensive fix that addresses both tag filtering AND parental rating filtering for music albums:
Fix Option 1: Simple Fix - Query Albums Directly
In SqliteItemRepository.cs, modify the GetMusicAlbums method:
public QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicAlbums(InternalItemsQuery query, CancellationToken cancellationToken)
{
    CheckDisposed();
    using IDatabaseConnection databaseConnection = CreateConnection(isReadOnly: true, cancellationToken);
    databaseConnection.BeginTransaction(BaseSqliteRepository.ReadTransactionMode);
    try
    {
        // FIXED: Don't use the special ItemLinks mechanism that breaks parental controls
        // Just query MusicAlbum items directly like regular items
        query.IncludeItemTypes = new string[1] { "MusicAlbum" };
        query.Recursive = true;
        
        // REMOVE these lines that cause the bug:
        // query.InnerIncludeItemTypes = FilterInnerIncludeItemTypes(query, TypesSupportingMusicAlbums);
        // query.AllowedGlobalItemLinkTypes = new ItemLinkType[1] { ItemLinkType.Albums };
        // query.AllowGlobalLists = false;
        // query.AllowAutoGlobalItemLinkTypesFromIncludeItemTypes = false;
        
        QueryResult<BaseItem> itemsInternal = GetItemsInternal(query, databaseConnection, cancellationToken);
        databaseConnection.CommitTransaction();
        return new QueryResult<Tuple<BaseItem, ItemCounts>>
        {
            TotalRecordCount = itemsInternal.TotalRecordCount,
            Items = itemsInternal.Items.Select((BaseItem i) => new Tuple<BaseItem, ItemCounts>(i, new ItemCounts())).ToArray()
        };
    }
    catch
    {
        databaseConnection.RollbackTransaction();
        throw;
    }
}
Fix Option 2: Complex Fix - Special Handling for Albums
If Emby wants to keep the ItemLinks mechanism for some reason, they need to add special handling for MusicAlbum queries in multiple places:
2a. Fix Tag Filtering
In GetContentRestrictionJoinCommandText method:
if (list2.Count > 0)  // list2 contains IncludeInheritedTags
{
    StringBuilder stringBuilder;
    string text2;
    if (query.AllowTagOrRating || contentRestrictionInfo.AllowTypesByTags.Length != 0)
    {
        stringBuilder = leftJoins;
        text2 = "left";
    }
    else
    {
        stringBuilder = joins;
        text2 = string.Empty;
    }
    
    // FIXED: Special handling for MusicAlbum queries
    if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes[0] == "MusicAlbum")
    {
        // For albums: Check if the album itself has the tag
        string text3 = text2 + " join ItemLinks2 ItemLinksIncludeInheritedTagIds on " +
            "ItemLinksIncludeInheritedTagIds.ItemId=" + AddQualifierToColumn("Id", mediaItemsTableQualifier) +
            " and ItemLinksIncludeInheritedTagIds.Type=4 and " + 
            BaseSqliteRepository.GetInOrEquals("ItemLinksIncludeInheritedTagIds.LinkedId", list2.ToArray());
        stringBuilder.Append(" " + text3);
    }
    else
    {
        // Original logic for non-album items (uses AncestorIds2)
        string text3 = text2 + " join AncestorIds2 AncestorIds2IncludeInheritedTagIds on " +
            "AncestorIds2IncludeInheritedTagIds.ItemId=" + AddQualifierToColumn("Id", mediaItemsTableQualifier);
        text3 = text3 + " " + text2 + " join ItemLinks2 ItemLinksIncludeInheritedTagIds on " +
            "AncestorIds2IncludeInheritedTagIds.AncestorId=ItemLinksIncludeInheritedTagIds.ItemId and " +
            "ItemLinksIncludeInheritedTagIds.Type=4 and " + 
            BaseSqliteRepository.GetInOrEquals("ItemLinksIncludeInheritedTagIds.LinkedId", list2.ToArray());
        stringBuilder.Append(" " + text3);
    }
}
2b. Fix Parental Rating Filtering
Create a new method for album rating queries:
private static string GetQueriedInheritedParentalRatingColumnForAlbums(string mediaItemsTableQualifier)
{
    // For albums, use the album's own InheritedParentalRatingValue directly
    // Don't look at ancestors since albums don't have them
    return "COALESCE(" + AddQualifierToColumn("InheritedParentalRatingValue", mediaItemsTableQualifier) + ", 0)";
}
Then modify where it's used:
// In the method that builds the query columns
if (HasQueriedInheritedParentalRatingValueCondition(query))
{
    string ratingColumn;
    if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes[0] == "MusicAlbum")
    {
        // FIXED: For albums, use their own rating
        ratingColumn = GetQueriedInheritedParentalRatingColumnForAlbums(mediaItemsTableQualifier);
    }
    else
    {
        // Original logic for non-albums
        ratingColumn = GetQueriedInheritedParentalRatingColumn(mediaItemsTableQualifier);
    }
    list.Add(ratingColumn + " as QueriedInheritedParentalRatingValue");
}
Why This Fix Works
The fix works because:
1. For tags: Instead of looking for tags on non-existent ancestors, we check if the album itself has the required tags
2. For ratings: Instead of looking for ratings on non-existent ancestors, we use the album's own InheritedParentalRatingValue field
3. Simpler approach: Or just query albums directly without the complex ItemLinks mechanism
Summary for Emby Team
The Bug: BOTH tag-based and rating-based parental controls are completely broken for the Albums view in music libraries.
Root Cause: The GetMusicAlbums method uses a special query mechanism that relies on the AncestorIds2 table to find parent folders for inheritance. But MusicAlbum entities are virtual and don't have ancestors in the file system, so:
- Tag filtering fails (looks for tags on non-existent ancestors)
- Rating filtering fails (looks for ratings on non-existent ancestors)
The Fix: Either:
1. Simple: Remove the special ItemLinks mechanism from GetMusicAlbums and query albums directly
2. Complex: Add special handling for MusicAlbum queries in both tag and rating filtering code
This is a critical bug that makes parental controls completely unusable for music libraries.

Posted

Hello mouth883,

** This is an auto reply **

Please wait for someone from staff support or our members to reply to you.

It's recommended to provide more info, as it explain in this thread:


Thank you.

Emby Team

mouth883
Posted

Here's a bit more info (from the AI)

I've identified the exact bug. When parental control tags are configured as "Only allow items with tags", the SQL query for the Albums view is fundamentally broken.
The Problem
The tag filtering for IncludeInheritedTags (used when "Only allow items with specific tags" is enabled) uses this SQL join:
1. Join AncestorIds2 table to find ancestors (parent folders) of the album
2. Join ItemLinks2 to check if those ancestors have the required tags
3. Filter to only show albums whose parent folders have the tags
But here's the critical flaw:
- Albums don't have ancestors with tags - they're virtual entities created from song metadata
- Songs have the tags (either directly or from their parent folders)
- The album entity itself might have tags, but the query doesn't check the album's own tags - only its ancestors' tags
Why It's Completely Broken
The query is checking:
Does this album have an ancestor (parent folder) that has the required tag?
But MusicAlbum entities are virtual - they don't have parent folders in the same way files do. So the answer is always NO, and no albums show up.
The Code That Needs Fixing
In SqliteItemRepository.GetContentRestrictionJoinCommandText(), around line 16000+, the tag filtering join for IncludeInheritedTags needs to be modified for MusicAlbum queries.
PROPOSED FIX
Here's the exact fix needed in SqliteItemRepository.cs:
Current Broken Code (simplified):
// In GetContentRestrictionJoinCommandText method
if (list2.Count > 0)  // list2 contains IncludeInheritedTags
{
    string joinType = (query.AllowTagOrRating || contentRestrictionInfo.AllowTypesByTags.Length != 0) 
        ? "left" : "";
    
    string text3 = joinType + " join AncestorIds2 AncestorIds2IncludeInheritedTagIds on " +
        "AncestorIds2IncludeInheritedTagIds.ItemId=" + AddQualifierToColumn("Id", mediaItemsTableQualifier);
    
    text3 = text3 + " " + joinType + " join ItemLinks2 ItemLinksIncludeInheritedTagIds on " +
        "AncestorIds2IncludeInheritedTagIds.AncestorId=ItemLinksIncludeInheritedTagIds.ItemId and " +
        "ItemLinksIncludeInheritedTagIds.Type=4 and " + 
        BaseSqliteRepository.GetInOrEquals("ItemLinksIncludeInheritedTagIds.LinkedId", list2.ToArray());
    
    stringBuilder.Append(" " + text3);
}
Fixed Code:
// In GetContentRestrictionJoinCommandText method
if (list2.Count > 0)  // list2 contains IncludeInheritedTags
{
    string joinType = (query.AllowTagOrRating || contentRestrictionInfo.AllowTypesByTags.Length != 0) 
        ? "left" : "";
    
    // Special handling for MusicAlbum queries
    if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes[0] == "MusicAlbum")
    {
        // For albums, check the album's own tags OR its children's tags
        string text3 = joinType + " join (" +
            // Check album's own tags
            "SELECT ItemId FROM ItemLinks2 WHERE Type=4 AND " + 
            BaseSqliteRepository.GetInOrEquals("LinkedId", list2.ToArray()) +
            " UNION " +
            // Check if any child songs have the tags (via their ancestors)
            "SELECT DISTINCT il.LinkedId as ItemId FROM ItemLinks2 il " +
            "INNER JOIN MediaItems mi ON mi.AlbumId = il.LinkedId " +
            "INNER JOIN AncestorIds2 ai ON ai.ItemId = mi.Id " +
            "INNER JOIN ItemLinks2 il2 ON il2.ItemId = ai.AncestorId " +
            "WHERE il.Type = 7 AND il2.Type = 4 AND " +
            BaseSqliteRepository.GetInOrEquals("il2.LinkedId", list2.ToArray()) +
            ") ItemLinksIncludeInheritedTagIds ON ItemLinksIncludeInheritedTagIds.ItemId = " + 
            AddQualifierToColumn("Id", mediaItemsTableQualifier);
        
        stringBuilder.Append(" " + text3);
    }
    else
    {
        // Original logic for non-album items
        string text3 = joinType + " join AncestorIds2 AncestorIds2IncludeInheritedTagIds on " +
            "AncestorIds2IncludeInheritedTagIds.ItemId=" + AddQualifierToColumn("Id", mediaItemsTableQualifier);
        
        text3 = text3 + " " + joinType + " join ItemLinks2 ItemLinksIncludeInheritedTagIds on " +
            "AncestorIds2IncludeInheritedTagIds.AncestorId=ItemLinksIncludeInheritedTagIds.ItemId and " +
            "ItemLinksIncludeInheritedTagIds.Type=4 and " + 
            BaseSqliteRepository.GetInOrEquals("ItemLinksIncludeInheritedTagIds.LinkedId", list2.ToArray());
        
        stringBuilder.Append(" " + text3);
    }
}
Alternative Simpler Fix:
An even simpler fix would be to modify GetMusicAlbums to not use the special ItemLinks query mechanism at all:
public QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicAlbums(InternalItemsQuery query, CancellationToken cancellationToken)
{
    CheckDisposed();
    using IDatabaseConnection databaseConnection = CreateConnection(isReadOnly: true, cancellationToken);
    databaseConnection.BeginTransaction(BaseSqliteRepository.ReadTransactionMode);
    try
    {
        // Don't use the ItemLinks mechanism for album queries
        // Just query MusicAlbum items directly like regular items
        query.IncludeItemTypes = new string[1] { "MusicAlbum" };
        query.Recursive = true;
        
        // Remove the special ItemLinks configuration that breaks tag filtering
        // query.InnerIncludeItemTypes = FilterInnerIncludeItemTypes(query, TypesSupportingMusicAlbums);
        // query.AllowedGlobalItemLinkTypes = new ItemLinkType[1] { ItemLinkType.Albums };
        // query.AllowGlobalLists = false;
        // query.AllowAutoGlobalItemLinkTypesFromIncludeItemTypes = false;
        
        QueryResult<BaseItem> itemsInternal = GetItemsInternal(query, databaseConnection, cancellationToken);
        databaseConnection.CommitTransaction();
        return new QueryResult<Tuple<BaseItem, ItemCounts>>
        {
            TotalRecordCount = itemsInternal.TotalRecordCount,
            Items = itemsInternal.Items.Select((BaseItem i) => new Tuple<BaseItem, ItemCounts>(i, new ItemCounts())).ToArray()
        };
    }
    catch
    {
        databaseConnection.RollbackTransaction();
        throw;
    }
}
Summary for Emby Team
Bug: Albums don't appear in the Albums view when parental control tags are configured as "Only allow items with specific tags", even when the albums and/or their songs are properly tagged.
Root Cause: The GetMusicAlbums query uses a special ItemLinks mechanism that looks for tags on an album's ancestors (parent folders) via the AncestorIds2 table. But MusicAlbum entities don't have ancestors in the traditional sense - they're virtual entities created from song metadata. The query should check:
1. The album's own tags
2. OR whether any of its child songs are accessible (have the required tags themselves or inherit them)
Fix: Either:
1. Modify the tag filtering join for MusicAlbum queries to check the album's own tags and its children's accessibility
2. Or simplify GetMusicAlbums to query albums directly without the ItemLinks mechanism
This bug makes parental controls completely unusable for music libraries when browsing by album.

Posted

Hi, try refreshing the metadata on the album and see if that helps.

mouth883
Posted
7 minutes ago, Luke said:

Hi, try refreshing the metadata on the album and see if that helps.

Yep tried that, didn't help

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...