projectdiscovery/katana · error

hijack pattern not set

Error message

hijack pattern not set

What it means

Hijack.Start panics with "hijack pattern not set" when h.enable is nil, meaning Hijack.Enable (or the pattern-configuring method) was never called before Start. The library treats this as a programming error: you cannot start intercepting requests without first specifying which URL pattern to hijack. It is a panic, not a returned error, so it must be prevented by correct setup order.

Source

Thrown at pkg/engine/hybrid/hijack.go:39

// Hijack is a hijack handler
type Hijack struct {
	page    *rod.Page
	enable  *proto.FetchEnable
	disable *proto.FetchDisable
	cancel  func()
}

// SetPattern set pattern directly
func (h *Hijack) SetPattern(pattern *proto.FetchRequestPattern) {
	h.enable = &proto.FetchEnable{
		Patterns: []*proto.FetchRequestPattern{pattern},
	}
}

// Start hijack.
func (h *Hijack) Start(handler HijackHandler) func() error {
	if h.enable == nil {
		panic("hijack pattern not set")
	}

	p, cancel := h.page.WithCancel()
	h.cancel = cancel

	err := h.enable.Call(p)
	if err != nil {
		return func() error { return err }
	}

	wait := p.EachEvent(func(e *proto.FetchRequestPaused) {
		if handler != nil {
			err = handler(e)
		}
	})

	return func() error {
		wait()

View on GitHub (pinned to e3e742739c)

Solutions

  1. Call hijack.Enable/with the desired URL pattern before invoking Start.
  2. Ensure the Hijack value is created through the library's constructor/helper that initializes the enable field, not as a zero-value struct literal.
  3. In code paths like navigateRequest, verify the pattern is configured before starting the hijack.
  4. Guard the call site with a nil check or recover() if the hijack setup is conditional.

Example fix

// before
h := &Hijack{page: page}
h.Start(handler) // panics: pattern never set
// after
h := &Hijack{page: page}
h.Enable("**/api/**") // set the hijack pattern first
h.Start(handler)
Defensive patterns

Strategy: validation

Validate before calling

// ensure the hijack is configured before starting
// (h.enable is internal; enforce ordering in your wrapper)
func startHijack(h *engine.Hijack, pattern string, handler engine.HijackHandler) (func() error, error) {
    if h == nil {
        return nil, errors.New("nil hijack")
    }
    h.Enable(pattern) // MUST precede Start
    return h.Start(handler), nil
}

Try / catch

// Go: it panics — wrap setup in recover during development
func safeStart(h *Hijack, handler HijackHandler) (stop func() error, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("hijack start: %v", r)
        }
    }()
    return h.Start(handler), nil
}

Prevention

When it happens

Trigger: Calling hijack.Start(handler) directly on a zero-value or freshly constructed Hijack struct; calling Start before Enable/pattern configuration; constructing Hijack manually instead of through the helper that sets the pattern.

Common situations: Refactoring moved the Enable call after Start; copying Hijack struct code without initializing the enable field; using the hijack API in a custom navigation flow (navigateRequest path) without the standard setup.

Related errors


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