danbooru/danbooru · error · AutotaggerClient::Error

Autotagger failed (code #{response.code})

Error message

Autotagger failed (code #{response.code})

What it means

AutotaggerClient#evaluate! POSTs the image file to <autotagger_url>/evaluate and raises AutotaggerClient::Error carrying the HTTP status code whenever the response is not 2xx. It is the strict variant used by the AI-tagging features (the tagme button and ai_tags controller actions); the soft evaluate returns {} on failure instead. A blank autotagger_url short-circuits to [] (feature disabled), so this error always means a configured autotagger service answered with an error status.

Source

Thrown at app/logical/autotagger_client.rb:44

    response = http.post("#{autotagger_url}/evaluate", form: { file: HTTP::FormData::File.new(file), threshold: confidence, format: "json" })
    return {} if !response.status.success?

    response.parse.first["tags"].with_indifferent_access
  end

  # Get the AI tags for an image as an array of AITags. Creates new tags if they don't already exist. Raises an error
  # if the API call fails.
  #
  # @param file [File] The image file.
  # @param limit [Integer] The maximum number of tags to return.
  # @param confidence [Float] The minimum confidence level for each tag.
  # @return [Array<AITag>] A list of new AI tags for this image. The `media_asset` field will be nil.
  def evaluate!(file, limit: 50, confidence: 0.01)
    return [] if autotagger_url.blank?

    response = http.post("#{autotagger_url}/evaluate", form: { file: HTTP::FormData::File.new(file), threshold: confidence, format: "json" })
    raise Error, "Autotagger failed (code #{response.code})" if !response.status.success?

    tag_names_with_scores = response.parse.first["tags"]
    tag_names = tag_names_with_scores.keys
    tags = Tag.where(name: tag_names).to_a

    missing_tags = tag_names - tags.pluck(:name)
    missing_tags.each do |name|
      tags << Tag.find_or_create_by_name(name, skip_name_validation: true)
    end

    tags.map do |tag|
      score = (100 * tag_names_with_scores[tag.name]).round
      AITag.new(tag: tag, score: score)
    end.sort_by(&:score)
  end
end

View on GitHub (pinned to 91fec09564)

Solutions

  1. Reproduce directly: curl -F file=@image.jpg -F threshold=0.01 -F format=json <autotagger_url>/evaluate and read the service's real error
  2. Check Danbooru.config.autotagger_url — correct scheme/host/port, and no /evaluate already appended
  3. Inspect the autotagger service logs and restart it; watch for model-load delay on the first request after startup
  4. On non-critical paths, switch to the soft AutotaggerClient#evaluate, which returns {} instead of raising

Example fix

# before (raises AutotaggerClient::Error on any non-2xx)
tags = AutotaggerClient.new.evaluate!(media_asset.file.open)

# after (degrade gracefully when AI tagging is optional)
tags = begin
  AutotaggerClient.new.evaluate!(media_asset.file.open)
rescue AutotaggerClient::Error => e
  Rails.logger.warn("Autotagger unavailable: #{e.message}")
  []
end
Defensive patterns

Strategy: fallback

Validate before calling

# Skip AI tagging when the service isn't configured (blank URL already returns [] server-side)
return if AutotaggerClient.new.autotagger_url.blank?

Try / catch

begin
  ai_tags = client.evaluate!(file)
rescue AutotaggerClient::Error => e
  Rails.logger.warn("autotagger: #{e.message}")
  ai_tags = [] # degrade gracefully; AI tags are optional metadata
end

Prevention

When it happens

Trigger: Triggering AI tagging (POST /uploads/:id/autotag or the ai_tags actions) while the autotagger service returns 4xx/5xx: autotagger_url pointing at the wrong host or path (404), the model worker down or not yet loaded (502/503 behind a proxy), an unreadable or oversized image, or a client/service version mismatch.

Common situations: Self-hosted autotagger container down or still loading its model on first request; Danbooru.config.autotagger_url misconfigured (wrong port, wrong base path — note the client appends /evaluate itself); reverse-proxy timeouts surfacing as 502/504; transient failures during bulk AI-tagging jobs.

Related errors


AI-assisted analysis of danbooru/danbooru@91fec09564 (2026-08-24). Data as JSON: /api/errors/b656b562c5e267d2. Report an issue: GitHub.