projectdiscovery/katana · warning

result is empty

Error message

result is empty

What it means

StandardWriter.Write returns this when the formatted output (data) produced for the result is zero bytes — after formatting via template, JSON, or screen mode, nothing was rendered. The writer refuses to emit empty output so blank lines and empty JSON objects are not written to files or screen.

Source

Thrown at pkg/output/output.go:263

	switch {
	case w.outputTemplate != nil:
		outputKind = "template"
		data, err = w.formatTemplate(result)
	case w.json:
		outputKind = "JSON"
		data, err = w.formatJSON(result)
	default:
		outputKind = "screen"
		data, err = w.formatScreen(result)
	}

	if err != nil {
		return errkit.Wrap(err, fmt.Sprintf("output: could not format %s output", outputKind))
	}

	if len(data) == 0 {
		return errors.New("result is empty")
	}

	// Increment result count only for valid results that produce output
	atomic.AddInt64(&w.resultCount, 1)

	w.outputMutex.Lock()
	defer w.outputMutex.Unlock()

	gologger.Silent().Msgf("%s", string(data))
	if w.outputFile != nil {
		if !w.json {
			data = decolorizerRegex.ReplaceAll(data, []byte(""))
		}
		if err := w.outputFile.Write(data); err != nil {
			return errkit.Wrap(err, "output: could not write to output")
		}
	}

View on GitHub (pinned to e3e742739c)

Solutions

  1. Check the output template: ensure at least one placeholder resolves non-empty for every result (e.g. include {{URL}}).
  2. Verify -omit-raw/-omit-body options are not stripping the only fields your template/screen format uses.
  3. Log result fields before Write to confirm which fields are empty for the failing result.
  4. Skip such results in the caller, or fall back to a default template that always renders the URL.

Example fix

// before
outputTemplate = "{{Body}}" // empty when -omit-body is set
// after
outputTemplate = "{{URL}} {{Body}}" // URL always non-empty
Defensive patterns

Strategy: validation

Validate before calling

func producesOutput(r *output.Result, tpl string, omitRaw, omitBody bool) bool {
    if tpl != "" {
        rendered := renderTemplate(tpl, r, omitRaw, omitBody)
        return strings.TrimSpace(rendered) != ""
    }
    return true
}

Try / catch

if err := writer.Write(result); err != nil {
    if err.Error() == "result is empty" {
        log.Warnf("rendered output empty for %s; check template/omit flags", result.Request.URL)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Calling Write(result) where formatTemplate/formatJSON/formatScreen returns success but an empty byte slice — typically an output template that resolves to an empty string for this result, or formatting fields that are all empty (e.g. after -omit-raw/-omit-body stripped everything).

Common situations: Custom output template whose placeholders evaluate to empty for certain results (missing fields, filtered attributes); using -omit-body/-omit-raw so screen output collapses to nothing; JSON output of a result stripped of all fields.

Related errors


AI-assisted analysis of projectdiscovery/katana@e3e742739c (2026-09-03). Data as JSON: /api/errors/a7a23f259ed73cc8. Report an issue: GitHub.