{"record":{"id":"638c3632fa8d268c","repo":"shadow1ng/fscan","slug":"webscan-poc-convert-failed","errorCode":"webscan_poc_convert_failed","errorMessage":"webscan_poc_convert_failed %s: %w","messagePattern":"webscan_poc_convert_failed (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"webscan/lib/Client.go","lineNumber":427,"sourceCode":"\t\t} else {\n\t\t\tcommon.LogError(i18n.Tr(\"webscan_poc_load_one_failed\", f, err))\n\t\t}\n\t}\n\treturn pocs\n}\n\n// parsePocYAML 解析POC YAML内容（提取公共逻辑）\nfunc parsePocYAML(data []byte, fileName string) (*Poc, error) {\n\t// 使用通用适配器加载POC（自动识别格式）\n\tuniversalPoc, err := LoadUniversalPoc(fileName, data)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%s %s: %w\", i18n.GetText(\"webscan_poc_parse_failed\"), fileName, err)\n\t}\n\n\t// 转换为fscan内部格式\n\tpoc, err := universalPoc.ToFscanPoc()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%s %s: %w\", i18n.GetText(\"webscan_poc_convert_failed\"), fileName, err)\n\t}\n\n\treturn poc, nil\n}\n\n// LoadPoc 从内嵌文件系统加载单个POC\nfunc LoadPoc(fileName string, Pocs embed.FS) (*Poc, error) {\n\t// 读取POC文件内容\n\tyamlFile, err := Pocs.ReadFile(\"pocs/\" + fileName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%s %s: %w\", i18n.GetText(\"webscan_poc_file_read_failed\"), fileName, err)\n\t}\n\n\t// 解析YAML内容\n\treturn parsePocYAML(yamlFile, fileName)\n}\n\n// SelectPoc 根据名称关键字选择POC文件","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/webscan/lib/Client.go#L409-L445","documentation":"parsePocYAML successfully parsed the YAML but ToFscanPoc() failed while converting the universal POC representation into fscan's internal *Poc format. This means the file is valid YAML but semantically invalid: required fields are missing, expression fields don't compile, or field values have the wrong type. The wrapped error from ToFscanPoc names the exact offending field.","triggerScenarios":"Calling LoadPoc(fileName, pocsFS) or LoadPocbyPath(path) with a POC whose yaml parses but whose rules/expressions/scripts contain invalid CEL expressions, unknown keys, or type-invalid values passed to ToFscanPoc.","commonSituations":"Hand-written or AI-generated POC YAML with malformed expression syntax, missing 'name'/'rules' sections, copy-pasted POCs from other scanner formats (nuclei/xray) that don't map to fscan's schema, or POCs written for an older fscan POC schema version.","solutions":["Read the wrapped %w error to find which field/expression ToFscanPoc rejected","Fix the CEL expression syntax in the POC's rules (verify operators, variable names like request/response exist)","Validate the POC against a known-good example in the pocs/ directory","If porting from nuclei/xray format, manually convert required fields to fscan POC schema"],"exampleFix":"# before (invalid CEL expression in POC)\nrules:\n  - method: GET\n    expression: \"response.status == 200 && response.body contains 'admin'\"\n# after (valid CEL using contains())\nrules:\n  - method: GET\n    expression: \"response.status == 200 && contains(response.body, 'admin')\"","handlingStrategy":"validation","validationCode":"data, _ := os.ReadFile(pocPath)\nvar up map[string]any\nif err := yaml.Unmarshal(data, &up); err != nil { return err }\nfor _, k := range []string{\"name\", \"rules\"} {\n    if _, ok := up[k]; !ok { return fmt.Errorf(\"poc missing field %q\", k) }\n}","typeGuard":null,"tryCatchPattern":"poc, err := LoadPocbyPath(path)\nif err != nil {\n    var convErr error\n    if errors.Unwrap(errors.Unwrap(err)) != nil { convErr = errors.Unwrap(errors.Unwrap(err)) }\n    log.Printf(\"poc %s invalid: %v\", path, convErr)\n    return\n}","preventionTips":["Lint every POC against a schema before adding it to pocs/","Test each POC against a known vulnerable target in CI","Keep expressions in CEL syntax; validate them with the CEL playground"],"tags":["go","poc","yaml","webscan","conversion"],"backgroundTag":"schema-validation-failed","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"}