{"record":{"id":"f5e4e941a7294dfd","repo":"kovidgoyal/kitty","slug":"failed-to-run-custom-processor-v-with-error-w","errorCode":null,"errorMessage":"Failed to run custom processor %#v with error: %w\\n%s","messagePattern":"Failed to run custom processor %#v with error: %w\\\\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kittens/hints/marks.go","lineNumber":681,"sourceCode":"\t\treturn nil\n\t}\n\n\tif opts.CustomizeProcessing != \"\" {\n\t\tcmd := exec.Command(utils.KittyExe(), append([]string{\"+runpy\", \"from kittens.hints.main import custom_marking; custom_marking()\"}, cli_args...)...)\n\t\tcmd.Stdin = strings.NewReader(sanitized_text)\n\t\tstdout, stderr := bytes.Buffer{}, bytes.Buffer{}\n\t\tcmd.Stdout, cmd.Stderr = &stdout, &stderr\n\t\terr = cmd.Run()\n\t\tif err != nil {\n\t\t\tvar e *exec.ExitError\n\t\t\tif errors.As(err, &e) && e.ExitCode() == 2 {\n\t\t\t\terr = run_basic_matching()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tgoto process_answer\n\t\t\t} else {\n\t\t\t\treturn \"\", nil, nil, fmt.Errorf(\"Failed to run custom processor %#v with error: %w\\n%s\", opts.CustomizeProcessing, err, stderr.String())\n\t\t\t}\n\t\t}\n\t\tans = make([]Mark, 0, 32)\n\t\terr = json.Unmarshal(stdout.Bytes(), &ans)\n\t\tif err != nil {\n\t\t\treturn \"\", nil, nil, fmt.Errorf(\"Failed to load output from custom processor %#v with error: %w\", opts.CustomizeProcessing, err)\n\t\t}\n\t\terr = adjust_python_offsets(sanitized_text, ans)\n\t\tif err != nil {\n\t\t\treturn \"\", nil, nil, fmt.Errorf(\"Custom processor %#v produced invalid mark output with error: %w\", opts.CustomizeProcessing, err)\n\t\t}\n\t} else if opts.Type == \"hyperlink\" {\n\t\tans = hyperlinks\n\t} else if opts.Type == \"word\" {\n\t\tans = mark_words(sanitized_text, opts)\n\t} else {\n\t\terr = run_basic_matching()\n\t\tif err != nil {","sourceCodeStart":663,"sourceCodeEnd":699,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/hints/marks.go#L663-L699","documentation":"The hints kitten ran a CustomizeProcessing custom-processor program; the program exited non-zero (or failed to start) and its stderr is appended to the error. The custom processor is expected to read hint options on stdin and emit JSON marks on stdout.","triggerScenarios":"Setting opts.CustomizeProcessing to a program that crashes, exits non-zero, or is not executable; the goto process_answer path shows a special-cased fallback exists only for the built-in matching path.","commonSituations":"Custom hint processor script has a Python exception, wrong interpreter shebang, missing file permission, or incompatible schema version between kitty and the script.","solutions":["Run the custom processor manually with the JSON options on stdin to see the appended stderr traceback","Fix the exception in the custom processor script","Ensure the path in CustomizeProcessing is executable and its kitty version matches the mark JSON schema"],"exampleFix":"# before\necho \"$opts\" | my_processor.py  # crashes\n# after\necho \"$opts\" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(\"[]\")'","handlingStrategy":"fallback","validationCode":"if err := checkExecutable(opts.CustomizeProcessing); err != nil { /* fall back to builtin matching */ }","typeGuard":null,"tryCatchPattern":"Wrap find_marks; on 'Failed to run custom processor' log the embedded stderr and fall back to run_basic_matching().","preventionTips":["Smoke-test the custom processor standalone with sample stdin JSON before wiring it in","Keep kitty and processor versions in sync; capture stderr for diagnostics"],"tags":["kitty","hints","custom-processor","subprocess"],"backgroundTag":"subprocess-exit-nonzero","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}