{"record":{"id":"2c3052c38df57311","repo":"shadow1ng/fscan","slug":"portfinger-probe-name-invalid","errorCode":null,"errorMessage":"portfinger_probe_name_invalid","messagePattern":"portfinger_probe_name_invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/portfinger/probe_parser.go","lineNumber":51,"sourceCode":"\n// parseProbeInfo 解析探测器信息，返回错误替代 panic\nfunc (p *Probe) parseProbeInfo(probeStr string) error {\n\tif len(probeStr) < 5 {\n\t\treturn fmt.Errorf(\"%s\", i18n.GetText(\"portfinger_probe_protocol_invalid\"))\n\t}\n\n\t// 提取协议和其他信息\n\tproto := probeStr[:4]\n\tother := probeStr[4:]\n\n\t// 验证协议类型\n\tif proto != \"TCP \" && proto != \"UDP \" {\n\t\treturn fmt.Errorf(\"%s\", i18n.GetText(\"portfinger_probe_protocol_invalid\"))\n\t}\n\n\t// 验证其他信息不为空\n\tif len(other) == 0 {\n\t\treturn fmt.Errorf(\"%s\", i18n.GetText(\"portfinger_probe_name_invalid\"))\n\t}\n\n\t// 解析指令\n\tdirective := p.getDirectiveSyntax(other)\n\tif directive.DirectiveName == \"\" || directive.Delimiter == \"\" {\n\t\treturn fmt.Errorf(\"%s\", i18n.GetText(\"portfinger_probe_name_invalid\"))\n\t}\n\n\t// 设置探测器属性\n\tp.Name = directive.DirectiveName\n\tp.Data = strings.Split(directive.DirectiveStr, directive.Delimiter)[0]\n\tp.Protocol = strings.ToLower(strings.TrimSpace(proto))\n\n\treturn nil\n}\n\n// 从字符串解析探测器信息\nfunc (p *Probe) fromString(data string) error {","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/core/portfinger/probe_parser.go#L33-L69","documentation":"After validating the 4-byte protocol prefix, parseProbeInfo splits the remainder of the probe line via getDirectiveSyntax. If the directive name or the delimiter cannot be determined (empty DirectiveName or Delimiter), the line is not a valid probe directive and this error is returned.","triggerScenarios":"A probe line has a valid \"TCP \"/\"UDP \" prefix but the rest of the line does not match the expected directive syntax (e.g. empty remainder handling, malformed directive without a recognizable name or delimiter), or getDirectiveSyntax fails after directive parsing. Also returned when the text after the protocol prefix is blank/whitespace-only (the len(other)==0 branch).","commonSituations":"Probe lines like \"TCP \" with nothing after it, lines truncated mid-directive, or copy-pasted probe lines that lost their payload after the protocol prefix.","solutions":["Ensure each probe line has a directive after the protocol prefix, e.g. \"TCP ProbeName^payload\".","Check for truncated lines caused by file encoding or line-splitting issues (CRLF, cut-off files).","Validate probe file content with a small test harness that calls fromString per line before deployment.","Compare the line against a known-good probe database to spot missing payload/delimiter characters."],"exampleFix":"// before\nTCP \n// after\nTCP ProbeName^data^end","handlingStrategy":"validation","validationCode":"func hasDirective(line string) bool {\n    rest := \"\"\n    if strings.HasPrefix(line, \"TCP \") { rest = line[4:] } else if strings.HasPrefix(line, \"UDP \") { rest = line[4:] }\n    return strings.TrimSpace(rest) != \"\"\n}","typeGuard":null,"tryCatchPattern":"probe, err := parser.FromString(data)\nif err != nil && strings.Contains(err.Error(), \"probe_name_invalid\") {\n    return fmt.Errorf(\"probe line missing directive: %w\", err)\n}","preventionTips":["Never leave a protocol prefix without a following directive","Keep probe lines on a single line (no embedded newlines)","Copy known-good probe lines as templates for custom probes"],"tags":["portfinger","parsing","validation","format"],"backgroundTag":"empty-required-field","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}