projectdiscovery/nuclei · error

[%v] invalid request id '%s' provided

Error message

[%v] invalid request id '%s' provided

What it means

In flow_internal.go, when a flow JS function is called with explicit request selectors — http("0") by index or dns("fetch-records") by request id — the flow looks up that id in reqMap built from the template's requests. A miss logs '[<template-id>] invalid request id '<id>' provided' via ctx.LogError, records a compile error in allErrs, and the protocol call returns the current matcher status (usually false), so downstream `if` logic takes the failure branch.

Source

Thrown at pkg/tmplexec/flow/flow_internal.go:66

				id := req.GetID()
				if id == "" {
					id, _ = reqMap.GetKeyWithValue(req)
				}
				err = f.allErrs.Set(opts.protoName+":"+id, err)
				if err != nil {
					f.ctx.LogError(fmt.Errorf("failed to store flow runtime errors got %v", err))
				}
				return matcherStatus.Load()
			}
		}
		return matcherStatus.Load()
	}

	// execution logic for http("0") or http("get-aws-vpcs")
	for _, id := range opts.reqIDS {
		req, ok := reqMap[id]
		if !ok {
			f.ctx.LogError(fmt.Errorf("[%v] invalid request id '%s' provided", f.options.TemplateID, id))
			// compile error
			if err := f.allErrs.Set(opts.protoName+":"+id, errkit.Newf("[%s] invalid request id '%s' provided", f.options.TemplateID, id)); err != nil {
				f.ctx.LogError(fmt.Errorf("failed to store flow runtime errors got %v", err))
			}
			return matcherStatus.Load()
		}
		// transform input if required
		inputItem := f.ctx.Input.Clone()
		if f.options.InputHelper != nil && f.ctx.Input.MetaInput.Input != "" {
			if inputItem.MetaInput.Input = f.options.InputHelper.Transform(inputItem.MetaInput.Input, req.Type()); inputItem.MetaInput.Input == "" {
				f.ctx.LogError(fmt.Errorf("failed to transform input for protocol %s", req.Type()))
				return false
			}
		}
		err := req.ExecuteWithResults(inputItem, output.InternalEvent(f.options.GetTemplateCtx(f.ctx.Input.MetaInput).GetAll()), output.InternalEvent{}, f.protocolResultCallback(req, matcherStatus, opts))
		// Mark the request as seen
		_ = f.executed.Set(requestKey(opts.protoName, req, id), struct{}{})
		if err != nil {

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Give each request an explicit `id:` and reference those ids in flow instead of positional indexes
  2. Fix the index: selectors are 0-based — the first request is http("0")
  3. Re-check every selector in the flow string against the template's request ids after any edit
  4. Smoke-test the template on a single host; -validate does not resolve flow selectors against requests, so a stale id passes validation

Example fix

# before
flow: |
  dns("fetch-recordss") && http()
dns:
  - name: fetch-records
    ...

# after
flow: |
  dns("fetch-records") && http()
dns:
  - name: fetch-records
    ...
Defensive patterns

Strategy: validation

Validate before calling

// Verify every selector in the flow string exists before running:
func flowSelectorsValid(flowSrc string, reqs []protocols.Request) bool {
    ids := map[string]bool{}
    for i, r := range reqs {
        ids[strconv.Itoa(i)] = true // index selectors are 0-based
        if id := r.GetID(); id != "" { ids[id] = true }
    }
    for _, m := range regexp.MustCompile(`(dns|http|tcp|ssl|websocket|whois|code|javascript|file)\("([^"]+)"\)`).FindAllStringSubmatch(flowSrc, -1) {
        if !ids[m[2]] { return false }
    }
    return true
}

Try / catch

// Invalid ids surface through ctx.LogError, not as a returned error:
// after Execute, scan for the pattern and fail the template validation pass:
if err := firstErrorContaining(ctx, "invalid request id"); err != nil {
    return fmt.Errorf("template %s references unknown request id: %w", tid, err)
}

Prevention

When it happens

Trigger: `flow: 'http("2")'` in a template with only two http requests (valid indexes are 0 and 1); referencing an id that doesn't exist: `dns("lookup-x")` when the dns request's id is `lookup-dns`; renaming a request's `id:` field without updating the flow string; quoting mistakes making '0' refer to a literal id named 0 instead of index 0.

Common situations: Refactoring flow templates: request sections get merged or deleted, leaving stale id references; template authors assuming 1-based indexing (it is 0-based); whitespace in the selector string (' http() ' vs 'http(" get")').

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/c91af31348e379e1. Report an issue: GitHub.