{"record":{"id":"4417921e00367a53","repo":"slimtoolkit/slim","slug":"malformed-change-path-matcher-s","errorCode":null,"errorMessage":"malformed change path matcher: %s","messagePattern":"malformed change path matcher: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/app/master/command/xray/cli.go","lineNumber":480,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\tmatchers = append(matchers, &m)\n\t}\n\n\treturn matchers, nil\n}\n\nfunc parseChangePathMatchers(values []string) ([]*dockerimage.ChangePathMatcher, error) {\n\tvar matchers []*dockerimage.ChangePathMatcher\n\n\tfor _, raw := range values {\n\t\tvar m dockerimage.ChangePathMatcher\n\n\t\tif strings.HasPrefix(raw, \"dump:\") {\n\t\t\tparts := strings.SplitN(raw, \":\", 3)\n\t\t\tif len(parts) != 3 {\n\t\t\t\treturn nil, fmt.Errorf(\"malformed change path matcher: %s\", raw)\n\t\t\t}\n\n\t\t\tm.Dump = true\n\n\t\t\toutTarget := strings.TrimSpace(parts[1])\n\t\t\tif len(outTarget) == 0 || outTarget == dockerimage.CDMDumpToConsole {\n\t\t\t\tm.DumpConsole = true\n\t\t\t} else {\n\t\t\t\tm.DumpDir = outTarget\n\t\t\t}\n\n\t\t\tm.PathPattern = parts[2]\n\n\t\t\t//\"dump:output:path_ptrn\"\n\t\t\t//\"::path_ptrn\"\n\t\t\t//\"path_ptrn\"\n\t\t} else {\n\t\t\tif !strings.HasPrefix(raw, \":\") {","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/slimtoolkit/slim/blob/81940d17fa112cc678e32209214bcb2355cb3004/pkg/app/master/command/xray/cli.go#L462-L498","documentation":"parseChangePathMatchers in the xray command (pkg/app/master/command/xray/cli.go:480) parses --change-path matcher values. A value starting with 'dump:' must have the 3-part form 'dump:output:path_pattern' (SplitN on ':' into exactly 3 parts); values like 'dump:console' or 'dump:/tmp/out' (2 fields) return \"malformed change path matcher: %s\".","triggerScenarios":"Passing a --change-path value beginning with 'dump:' that lacks the trailing path-pattern field, e.g. 'dump:console' or 'dump:/tmp/out' — fewer than 3 colon-separated fields.","commonSituations":"Users assume 'dump:/tmp/out' is enough and forget the pattern field; translating data-matcher syntax (4 fields) to path-matcher syntax (3 fields) incorrectly; examples copied from data-matcher docs.","solutions":["Use the full 3-field form: dump:<output-dir-or-empty>:<path-pattern>, e.g. dump:/tmp/out:'*.conf' or dump::'/etc/.*'.","If the path pattern is empty, still include the trailing separator: 'dump:/tmp/out:'.","Note path matchers take one fewer field than data matchers (3, not 4) — don't mix the syntaxes.","Sanity check: the value must contain exactly 2 colons when prefixed with 'dump:'."],"exampleFix":"// before\n--change-path 'dump:/tmp/out'\n// after\n--change-path 'dump:/tmp/out:*.conf'","handlingStrategy":"validation","validationCode":"// validate a dump-form change-path matcher before invoking the CLI\nfunc validDumpPathMatcher(raw string) bool {\n    if !strings.HasPrefix(raw, \"dump:\") {\n        return true\n    }\n    return len(strings.SplitN(raw, \":\", 3)) == 3\n}","typeGuard":null,"tryCatchPattern":"matchers, err := parseChangePathMatchers(values)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"malformed change path matcher\") {\n        fmt.Fprintf(os.Stderr, \"expected dump:out:path_pattern (2 colons): %v\\n\", err)\n        os.Exit(2)\n    }\n    return err\n}","preventionTips":["Path matcher dump form = 3 fields (2 colons): dump:out:path_pattern.","Don't copy data-matcher examples — their dump form has one extra field.","Include the pattern even when dumping, e.g. dump:/tmp/out:'*.conf'.","Use single quotes in shell to keep glob/regex characters intact."],"tags":["cli","xray","matcher-syntax","slimtoolkit"],"backgroundTag":"malformed-matcher-syntax","analyzedSha":"81940d17fa112cc678e32209214bcb2355cb3004","analyzedAt":"2026-08-31T23:06:12.682Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}