{"record":{"id":"29ce812b46dba296","repo":"v2rayA/v2rayA","slug":"tinytun-route-script-s-w","errorCode":null,"errorMessage":"tinytun route script (%s): %w","messagePattern":"tinytun route script \\((.+?)\\): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/kernel/v2ray/tinytun_enabled.go","lineNumber":729,"sourceCode":"\tcase \"cmd\":\n\t\treturn shellInfo{bin: \"cmd.exe\", scriptFlag: \"/C\", ext: \".bat\"}, nil\n\tcase \"git_bash\":\n\t\treturn shellInfo{bin: \"bash.exe\", ext: \".sh\"}, nil\n\tdefault:\n\t\treturn shellInfo{}, fmt.Errorf(\"unknown shell type: %v\", shellType)\n\t}\n}\n\n// runTinyTunScript writes the given script to a temp file and executes it\n// with the configured shell.  stage is only used for logging.\nfunc runTinyTunScript(stage, script string) error {\n\tif strings.TrimSpace(script) == \"\" {\n\t\treturn nil\n\t}\n\tsetting := configure.GetSettingNotNil()\n\tsi, err := resolveShellInfo(setting.TunRouteShellType, setting.TunRouteShellPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"tinytun route script (%s): %w\", stage, err)\n\t}\n\n\t// Resolve the shell binary via PATH if it is not an absolute path.\n\tbinPath := si.bin\n\tif !filepath.IsAbs(binPath) {\n\t\tif resolved, err := exec.LookPath(binPath); err == nil {\n\t\t\tbinPath = resolved\n\t\t}\n\t}\n\n\t// Write script to a temp file with restricted permissions.\n\ttmpFile, err := os.CreateTemp(\"\", \"tinytun_*\"+si.ext)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"tinytun route script (%s): failed to create temp file: %w\", stage, err)\n\t}\n\tdefer os.Remove(tmpFile.Name())\n\n\t// Restrict permissions immediately after creation (before writing content).","sourceCodeStart":711,"sourceCodeEnd":747,"githubUrl":"https://github.com/v2rayA/v2rayA/blob/71e5442fc548c05680ee55eae943e6c0afe9ac51/service/kernel/v2ray/tinytun_enabled.go#L711-L747","documentation":"runTinyTunScript wraps errors from resolveShellInfo with the stage name (e.g. pre/post route change) to give context about which script invocation failed. It means the shell type/path configured for tinytun route scripts could not be resolved into an executable spec (empty custom path or unknown shell type). No command was attempted yet.","triggerScenarios":"runTinyTunScript at tinytun_enabled.go:729 calls resolveShellInfo(setting.TunRouteShellType, setting.TunRouteShellPath) and receives an error — custom shell with empty path, or unknown shellType string.","commonSituations":"Same root causes as the underlying resolveShellInfo errors: blank custom shell path, misspelled or unsupported shell type in settings; surfacing after a tun route change triggers a script run.","solutions":["Inspect the inner error in the %w chain: 'custom shell path is empty' → set the path; 'unknown shell type' → use a supported value.","Correct TunRouteShellType/TunRouteShellPath in settings.","Disable the tun route script for that stage if scripts are not needed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"si, err := resolveShellInfo(setting.TunRouteShellType, setting.TunRouteShellPath)\nif err != nil {\n    return fmt.Errorf(\"tun route script disabled: %w\", err)\n}\nif _, err := exec.LookPath(si.bin); err != nil {\n    return fmt.Errorf(\"shell %q not found in PATH\", si.bin)\n}","typeGuard":null,"tryCatchPattern":"if err := runTinyTunScript(stage, script); err != nil {\n    log.Warnf(\"%v — skipping route script\", err)\n    return nil // degrade gracefully, keep tunnel running\n}","preventionTips":["Validate shell settings at save time, not at script-run time","Keep TunRouteShellPath absolute when using custom shells","Check the inner resolveShellInfo error to know which fix applies","Skip route scripts gracefully when shell config is invalid"],"tags":["validation","config","shell","tinytun"],"backgroundTag":"invalid-shell-configuration","analyzedSha":"71e5442fc548c05680ee55eae943e6c0afe9ac51","analyzedAt":"2026-09-05T20:04:37.459Z","contentChangedAt":"2026-09-05T20:04:37.459Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}