Tag Manager

:placard: Summary Match and sync local tags with stash-box endpoints. Bulk cleanup your tag library with smart layered matching (exact, alias, fuzzy, synonym) and field-by-field merge dialog.
:link: Repository https://github.com/carrotwaxr/stash-plugins/tree/main/plugins/tagManager
:information_source: Source URL https://carrotwaxr.github.io/stash-plugins/stable/index.yml
:open_book: Install How to install a plugin?

Tag Manager

Match and sync your local tags with StashDB (or other stash-box instances). Browse unmatched tags, find matches with smart layered search, and update tags with a field-by-field merge dialog.

:link: Links

:white_check_mark: Requirements

  • Stash 0.30+ (requires stash_ids field on tags)
  • At least one stash-box endpoint configured (Settings → Metadata Providers → Stash-Box Endpoints)
  • Python 3.8+

Python Dependencies (Optional)

The plugin works without any pip dependencies - you’ll have exact, alias, and synonym matching. Installing the optional packages enables fuzzy matching:

Package Purpose Required?
thefuzz Fuzzy string matching (typos, plurals) Optional
python-Levenshtein Speeds up thefuzz 4-10x Optional

Docker:

docker exec -it stash /root/.stash/venv/bin/pip install thefuzz python-Levenshtein

Mac / Native Install:
Find your Python path in Settings → System → Application Paths → Python Executable, then:

/path/to/your/python -m pip install thefuzz python-Levenshtein

If Python is giving you trouble, skip this step entirely - the plugin still works, just without fuzzy matching.

:package: Installation

  1. Go to Settings → Plugins → Available Plugins
  2. Add source: https://carrotwaxr.github.io/stash-plugins/stable/index.yml
  3. Click Reload and install “Tag Manager”
  4. (Optional) Install Python dependencies for fuzzy matching (see above)

:sparkles: Features

  • Multi-endpoint support - Select from any configured stash-box (StashDB, FansDB, etc.)
  • Tag caching - Caches all tags locally with 24-hour expiry for fast searches
  • Smart matching - Layered search: exact name → alias → synonym → fuzzy
  • One-click accept - Quick accept for high-confidence matches
  • Field-by-field merge - Choose what to keep vs. update for each field
  • Manual search - Search the stash-box directly for edge cases
  • Stash-box linking - Adds stash_ids to tags for future syncing
  • Tag Hierarchy View - Browse your tags in a visual tree showing parent/child relationships
  • Scene Tag Sync - Bulk sync tags from StashDB to your scenes (see below)

:label: Tag Matching

Access via the tags icon button on the Tags page, or navigate to /plugins/tag-manager.

Workflow

  1. Select your stash-box endpoint from the dropdown
  2. The plugin loads cached tags (or fetches them if no cache exists)
  3. Click Find Matches for Page to search all visible unmatched tags
  4. For each match:
    • Accept - Opens diff dialog with smart defaults
    • More - View all potential matches or search manually
  5. In the diff dialog, choose what to update:
    • Keep - Keep your current value
    • Keep + Add alias - Keep your name, add stash-box name as alias
    • StashDB - Use the stash-box value (your old name auto-added as alias)

Match Types

Type Color Description
exact Green Exact name match (case-insensitive)
alias Blue Matched via stash-box alias
synonym Purple Matched via custom synonym mapping
fuzzy Yellow Fuzzy string match (requires thefuzz)

:deciduous_tree: Tag Hierarchy

Access via the sitemap icon button on the Tags page, or navigate to /plugins/tag-hierarchy.

  • Browse tags in a tree view showing parent/child relationships
  • Click arrows to expand/collapse branches
  • Use “Expand All” / “Collapse All” for quick navigation
  • Toggle “Show images” to display tag thumbnails

:counterclockwise_arrows_button: Scene Tag Sync (v0.3.0+)

Automatically sync tags from StashDB to your local scenes. Run via Settings → Tasks → “Sync Scene Tags from StashDB”.

How it works

  1. Finds all scenes with StashDB IDs
  2. Fetches tag data from StashDB for each scene
  3. Matches StashDB tags to your local tags (by stash_id link, name, or alias)
  4. Merges new tags into your scenes

Important notes

  • Dry run enabled by default - Preview mode shows what would change without modifying anything
  • Dry run caps at 200 scenes - For safety when previewing large libraries
  • Only adds existing local tags - Won’t create new tags, only adds tags you already have
  • Uses efficient batch querying (fingerprints first, then fallback to ID lookup)

Settings

Setting Description Default
Scene Tag Sync - Dry Run Preview without making changes Enabled

:floppy_disk: Tag Caching

Fetching all tags from a stash-box takes 20-40 seconds. The plugin caches tags locally:

  • Cache location: plugins/tagManager/cache/
  • Cache expiry: 24 hours (auto-refreshes on next use)
  • Manual refresh: Click “Refresh Cache” to force update
  • Per-endpoint: Each stash-box has its own cache file

Cache status indicator:

  • :green_circle: Green - Valid cache with tag count and age
  • :yellow_circle: Yellow - Cache expired (will refresh automatically)
  • :white_circle: Gray - No cache yet (will fetch on first use)

:gear: Plugin Settings

Go to Settings → Plugins → Tag Manager:

Setting Description Default
Enable Fuzzy Search Use fuzzy matching (requires thefuzz) Enabled
Enable Synonym Search Use custom synonym mappings Enabled
Fuzzy Threshold Minimum score (0-100) for fuzzy matches 80
Page Size Tags per page 25
Scene Tag Sync - Dry Run Preview sync without changes Enabled

:memo: Custom Synonyms

Edit plugins/tagManager/synonyms.json to add custom mappings:

{
  "synonyms": {
    "Your Local Tag": ["StashDB Tag 1", "StashDB Tag 2"]
  }
}

:wrench: Troubleshooting

Common Issues

  1. “No Stash-Box Configured” - Add a stash-box in Settings → Metadata Providers
  2. “thefuzz not installed” - Fuzzy matching disabled; install the package or ignore if you don’t need it
  3. Cache takes too long - First fetch is slow (~30s); subsequent loads use cache
  4. No matches found - Try “Refresh Cache” to update the tag list

Debug Logging

Check Stash logs (Settings → Logs) for detailed output:

  • Info - High-level operations (cache hits, sync progress)
  • Debug - Detailed info (endpoints, matches found)
  • Trace - Very detailed (individual requests)
4 Likes

:label: v0.3.0 - Scene Tag Sync from StashDB

New feature that automatically syncs tags from StashDB to your local scenes.

:sparkles: What’s New

Sync Scene Tags from StashDB - A new Plugin Task that:

  • Fetches tags from StashDB for all scenes with StashIDs
  • Matches them to your local tags (by StashDB link, name, or alias)
  • Merges new tags with existing tags (never removes tags)

:gear: New Setting

Setting Description Default
Scene Tag Sync - Dry Run Preview what tags would be added without making changes. Caps at 200 scenes. Enabled

:open_book: How to Use

  1. Reload plugins: Settings → Plugins → Reload Plugins
  2. Run the task: Plugin Tasks → “Sync Scene Tags from StashDB”
  3. Check logs: Settings → Logs

:test_tube: Testing (Recommended)

  1. Keep Dry Run enabled (default)

  2. Run the task

  3. Check logs for preview output:
    [DRY RUN] Scene 123: would add 3 tags: [‘Blonde’, ‘Cowgirl’, ‘Anal’]

  4. Verify matches look correct

  5. Disable dry run in plugin settings and run again to apply

:wrench: Technical Details

  • Uses batch fingerprint queries (40 scenes/request) for efficiency
  • Falls back to sequential queries when fingerprints don’t match
  • Rate-limited to 2 req/sec to respect StashDB’s API limits
  • Only adds tags that already exist locally — won’t create new tags
  • Tags are matched by: StashDB ID link → name → alias (same priority as Stash’s Tagger)

:memo: Changelog

  • v0.3.0 - Scene tag sync from StashDB
2 Likes

The use case for the above feature is that I had not been using Stash’s “Include tags” when scraping scenes, because when I started using Stash way back when, the tags were not great and seemed to be directly from the studio which were often incorrect. Anyway, after Stash 0.30 I started really utilizing Tags to their fullest and realized I had a LOT of Scenes that didn’t have their StashDB tags added to them. So I went and used the Tagger to manually do a few hundred and saw that I was just repeating the same exact manual steps every time (I added several new useful tags during the manual process, and aliased some existing ones so they’d link up nicely). So I wanted a way to automate “catching my library up”.

This would also be useful to do periodically after you add/organize Tags or think StashDB might have updated the tag associations on some of your Scenes

Now that we have stash IDs for tags I’ve been using this to sync my tag descriptions and aliases with stash DB. This has worked great for that, thank you.

It might be nice to have an append or overwrite option for the stash IDs field. In my testing, this plugin seems to always overwrite the value saved in stash ID. The use case would be when dealing with multiple endpoints.

For example, fans DB has tag “High Heels” whereas stash DB has “Woman’s Heels” as tag name with “High Heels” as an alias. Depending on how one has the tag named in their local stash, this will fail to match the tag when submitting a scene draft to one of those DBs. If both IDs are on the tag, then it will match correctly to either DB when submitting a draft.

Would it be possible to add a search function for tags? This would be especially useful when looking for a stashdb tag to import because I am not always sure which parent tag it would be under.

Great idea. You mean in the Browse StashDB tab you want the ability to search?

Yes exactly!

Discourse is making me write 20 characters to say yes :slight_smile: