urbanadventurer/WhatWeb · error

Error: # is a directory

Error message

Error: #{@target} is a directory

What it means

Raised in Target#initialize (lib/target.rb:186) when the target string or path supplied to Target.new points to an existing directory. WhatWeb targets must be a URL, a single file, or an IP/host — a directory cannot be opened or scanned, so construction aborts immediately.

Solutions

  1. Pass a single file or URL, not a directory
  2. Enumerate the directory yourself and pass a file list (whatweb dir/* or build a target file with -i)
  3. If you intended a URL list file, point to the file containing targets, not the folder holding it
  4. Add a shell pre-check: [ -f "$TARGET" ] || [ -d "$TARGET" ] before invoking

Example fix

// before
whatweb ./targets/
// after
whatweb ./targets/*.txt
// or
whatweb --input-file=./targets/list.txt
Defensive patterns

Strategy: validation

Validate before calling

target = ARGV[0]
raise 'target is a directory' if File.directory?(target) rescue false
# or in shell: [ -d "$TARGET" ] && echo 'pass a file or URL, not a directory'

Type guard

def scannable_target?(t)
  t.is_a?(String) && !t.empty? && (t =~ URI::DEFAULT_PARSER.make_regexp || (File.file?(t) && File.readable?(t)))
end

Try / catch

begin
  target = Target.new(path)
rescue RuntimeError => e
  next unless e.message.include?('is a directory')
  puts "#{path} is a directory; expand to files first"
end

Prevention

When it happens

Trigger: Target.new('some/dir') or running whatweb with a CLI argument that is an existing directory path (File.exist? true and File.directory? true).

Common situations: Passing a directory containing target files instead of the files themselves; forgetting to expand a glob ('./targets/*' unexpanded); typo where a path was meant to be a file; scripting that passes $PWD or a folder of exports as the target.

Related errors


AI-assisted analysis of urbanadventurer/WhatWeb@d279d93042 (2026-09-15). Data as JSON: /api/errors/a000df55d2f03759. Report an issue: GitHub.

Appendix: source

Thrown at lib/target.rb:186

    @is_url
  end

  def initialize(target = nil, redirect_counter = 0)
    @target = target
    @redirect_counter = redirect_counter
    @headers = {}
    @http_options = { method: 'GET' }
    #		@status=0

    @is_url = if @target =~ /^http[s]?:\/\//
                true
              else
                false
              end

    if File.exist?(@target)
      @is_file = true
      raise "Error: #{@target} is a directory" if File.directory?(@target)
      if File.readable?(@target) == false
        raise "Error: You do not have permission to view #{@target}"
      end
    else
      @is_file = false
    end

    if is_url?
      @uri = URI.parse(Addressable::URI.encode(@target))

      # is this taking control away from the user?
      # [400] http://www.alexa.com  [200] http://www.alexa.com/
      @uri.path = '/' if @uri.path.empty?
    else
      # @uri=URI.parse("file://"+@target)
      @uri = URI.parse('')
    end
  end

View on GitHub (pinned to d279d93042)