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
- Give each request an explicit `id:` and reference those ids in flow instead of positional indexes
- Fix the index: selectors are 0-based — the first request is http("0")
- Re-check every selector in the flow string against the template's request ids after any edit
- 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
- Always give requests explicit `id:` fields and reference ids, never indexes
- Re-run flow smoke tests after any request merge/rename
- Remember selectors are 0-based when using numeric strings
- `nuclei -validate` does not resolve selectors — add your own pre-check
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
- could not compile flow: %s
- could not create flow executor: %s
- invalid request type %s
- validation failed for these fields
- both verbose and silent mode specified
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/c91af31348e379e1.
Report an issue: GitHub.