{"record":{"id":"c91af31348e379e1","repo":"projectdiscovery/nuclei","slug":"v-invalid-request-id-s-provided","errorCode":null,"errorMessage":"[%v] invalid request id '%s' provided","messagePattern":"\\[(.+?)\\] invalid request id '(.+?)' provided","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tmplexec/flow/flow_internal.go","lineNumber":66,"sourceCode":"\t\t\t\tid := req.GetID()\n\t\t\t\tif id == \"\" {\n\t\t\t\t\tid, _ = reqMap.GetKeyWithValue(req)\n\t\t\t\t}\n\t\t\t\terr = f.allErrs.Set(opts.protoName+\":\"+id, err)\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.ctx.LogError(fmt.Errorf(\"failed to store flow runtime errors got %v\", err))\n\t\t\t\t}\n\t\t\t\treturn matcherStatus.Load()\n\t\t\t}\n\t\t}\n\t\treturn matcherStatus.Load()\n\t}\n\n\t// execution logic for http(\"0\") or http(\"get-aws-vpcs\")\n\tfor _, id := range opts.reqIDS {\n\t\treq, ok := reqMap[id]\n\t\tif !ok {\n\t\t\tf.ctx.LogError(fmt.Errorf(\"[%v] invalid request id '%s' provided\", f.options.TemplateID, id))\n\t\t\t// compile error\n\t\t\tif err := f.allErrs.Set(opts.protoName+\":\"+id, errkit.Newf(\"[%s] invalid request id '%s' provided\", f.options.TemplateID, id)); err != nil {\n\t\t\t\tf.ctx.LogError(fmt.Errorf(\"failed to store flow runtime errors got %v\", err))\n\t\t\t}\n\t\t\treturn matcherStatus.Load()\n\t\t}\n\t\t// transform input if required\n\t\tinputItem := f.ctx.Input.Clone()\n\t\tif f.options.InputHelper != nil && f.ctx.Input.MetaInput.Input != \"\" {\n\t\t\tif inputItem.MetaInput.Input = f.options.InputHelper.Transform(inputItem.MetaInput.Input, req.Type()); inputItem.MetaInput.Input == \"\" {\n\t\t\t\tf.ctx.LogError(fmt.Errorf(\"failed to transform input for protocol %s\", req.Type()))\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\terr := req.ExecuteWithResults(inputItem, output.InternalEvent(f.options.GetTemplateCtx(f.ctx.Input.MetaInput).GetAll()), output.InternalEvent{}, f.protocolResultCallback(req, matcherStatus, opts))\n\t\t// Mark the request as seen\n\t\t_ = f.executed.Set(requestKey(opts.protoName, req, id), struct{}{})\n\t\tif err != nil {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/tmplexec/flow/flow_internal.go#L48-L84","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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\")').","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"],"exampleFix":"# before\nflow: |\n  dns(\"fetch-recordss\") && http()\ndns:\n  - name: fetch-records\n    ...\n\n# after\nflow: |\n  dns(\"fetch-records\") && http()\ndns:\n  - name: fetch-records\n    ...","handlingStrategy":"validation","validationCode":"// Verify every selector in the flow string exists before running:\nfunc flowSelectorsValid(flowSrc string, reqs []protocols.Request) bool {\n    ids := map[string]bool{}\n    for i, r := range reqs {\n        ids[strconv.Itoa(i)] = true // index selectors are 0-based\n        if id := r.GetID(); id != \"\" { ids[id] = true }\n    }\n    for _, m := range regexp.MustCompile(`(dns|http|tcp|ssl|websocket|whois|code|javascript|file)\\(\"([^\"]+)\"\\)`).FindAllStringSubmatch(flowSrc, -1) {\n        if !ids[m[2]] { return false }\n    }\n    return true\n}","typeGuard":null,"tryCatchPattern":"// Invalid ids surface through ctx.LogError, not as a returned error:\n// after Execute, scan for the pattern and fail the template validation pass:\nif err := firstErrorContaining(ctx, \"invalid request id\"); err != nil {\n    return fmt.Errorf(\"template %s references unknown request id: %w\", tid, err)\n}","preventionTips":["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"],"tags":["flow","request-id","template","selector"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}