shadow1ng/fscan · error

webscan_poc_convert_failed

webscan_poc_convert_failed

Error message

webscan_poc_convert_failed %s: %w

What it means

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.

Source

Thrown at webscan/lib/Client.go:427

		} else {
			common.LogError(i18n.Tr("webscan_poc_load_one_failed", f, err))
		}
	}
	return pocs
}

// parsePocYAML 解析POC YAML内容(提取公共逻辑)
func parsePocYAML(data []byte, fileName string) (*Poc, error) {
	// 使用通用适配器加载POC(自动识别格式)
	universalPoc, err := LoadUniversalPoc(fileName, data)
	if err != nil {
		return nil, fmt.Errorf("%s %s: %w", i18n.GetText("webscan_poc_parse_failed"), fileName, err)
	}

	// 转换为fscan内部格式
	poc, err := universalPoc.ToFscanPoc()
	if err != nil {
		return nil, fmt.Errorf("%s %s: %w", i18n.GetText("webscan_poc_convert_failed"), fileName, err)
	}

	return poc, nil
}

// LoadPoc 从内嵌文件系统加载单个POC
func LoadPoc(fileName string, Pocs embed.FS) (*Poc, error) {
	// 读取POC文件内容
	yamlFile, err := Pocs.ReadFile("pocs/" + fileName)
	if err != nil {
		return nil, fmt.Errorf("%s %s: %w", i18n.GetText("webscan_poc_file_read_failed"), fileName, err)
	}

	// 解析YAML内容
	return parsePocYAML(yamlFile, fileName)
}

// SelectPoc 根据名称关键字选择POC文件

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Read the wrapped %w error to find which field/expression ToFscanPoc rejected
  2. Fix the CEL expression syntax in the POC's rules (verify operators, variable names like request/response exist)
  3. Validate the POC against a known-good example in the pocs/ directory
  4. If porting from nuclei/xray format, manually convert required fields to fscan POC schema

Example fix

# before (invalid CEL expression in POC)
rules:
  - method: GET
    expression: "response.status == 200 && response.body contains 'admin'"
# after (valid CEL using contains())
rules:
  - method: GET
    expression: "response.status == 200 && contains(response.body, 'admin')"
Defensive patterns

Strategy: validation

Validate before calling

data, _ := os.ReadFile(pocPath)
var up map[string]any
if err := yaml.Unmarshal(data, &up); err != nil { return err }
for _, k := range []string{"name", "rules"} {
    if _, ok := up[k]; !ok { return fmt.Errorf("poc missing field %q", k) }
}

Try / catch

poc, err := LoadPocbyPath(path)
if err != nil {
    var convErr error
    if errors.Unwrap(errors.Unwrap(err)) != nil { convErr = errors.Unwrap(errors.Unwrap(err)) }
    log.Printf("poc %s invalid: %v", path, convErr)
    return
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/638c3632fa8d268c. Report an issue: GitHub.