{"record":{"id":"7891800dd0817419","repo":"larksuite/cli","slug":"s-w","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/vfs/localfileio/path.go","lineNumber":117,"sourceCode":"\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc isWindowsNonLocalNamespace(path string) bool {\n\tnormalized := strings.ReplaceAll(path, \"/\", `\\`)\n\treturn strings.HasPrefix(normalized, `\\\\`) || strings.HasPrefix(normalized, `\\??\\`)\n}\n\n// SafeLocalFlagPath validates a flag value as a local file path.\n// Empty values and http/https URLs are returned unchanged without validation.\nfunc SafeLocalFlagPath(flagName, value string) (string, error) {\n\tif value == \"\" || strings.HasPrefix(value, \"http://\") || strings.HasPrefix(value, \"https://\") {\n\t\treturn value, nil\n\t}\n\tif _, err := SafeInputPath(value); err != nil {\n\t\treturn \"\", fmt.Errorf(\"%s: %w\", flagName, err)\n\t}\n\treturn value, nil\n}\n\n// SafeEnvDirPath validates an environment-provided application directory path.\n// It requires an absolute path, rejects control characters, normalizes the\n// input, and resolves symlinks through the nearest existing ancestor.\nfunc SafeEnvDirPath(path, envName string) (string, error) {\n\tif err := charcheck.RejectControlChars(path, envName); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tpath = filepath.Clean(path)\n\tif !filepath.IsAbs(path) {\n\t\treturn \"\", fmt.Errorf(\"%s must be an absolute path, got %q\", envName, path)\n\t}\n\n\tresolved, err := resolveNearestAncestor(path)","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/vfs/localfileio/path.go#L99-L135","documentation":"SafeLocalFlagPath validates a flag value as a local file path by delegating to SafeInputPath; on failure it prefixes the error with the flag name. Empty values and http/https URLs bypass validation entirely, so this fires only for non-URL local path values that fail the strict path policy.","triggerScenarios":"Calling SafeLocalFlagPath(flagName, value) where value is a non-empty local (non-http/https) string that SafeInputPath rejects — outside the allowlist, containing control characters, a foreign absolute path like C:\\x on Unix, a ~/ literal reading outside the policy, etc.","commonSituations":"Passing a file:// or other scheme URL that isn't http/https; passing a Windows path on Linux; pointing at a file outside cwd, /tmp, or ~/files; a flag intended for a URL given a local path.","solutions":["Read the wrapped %w cause to see which policy check failed and move the file accordingly (cwd, /tmp, or ~/files)","If the value is a URL, use an http:// or https:// URL (those bypass path validation)","Use a relative path that stays inside the current working directory","If the file must come from anywhere, pass it via stdin (\"-\") instead of a path"],"exampleFix":"// before\nlark cmd --attachment /etc/hosts\n// error: --attachment: --file \"/etc/hosts\" resolves outside the allowed roots\n// after\ncp /etc/hosts /tmp/hosts.txt && lark cmd --attachment /tmp/hosts.txt","handlingStrategy":"validation","validationCode":"if v != \"\" && !strings.HasPrefix(v, \"http://\") && !strings.HasPrefix(v, \"https://\") {\n    if _, err := os.Stat(v); err != nil {\n        return fmt.Errorf(\"%s: local file %q unavailable: %w\", flag, v, err)\n    }\n}","typeGuard":"func isHTTPURL(v string) bool {\n    return strings.HasPrefix(v, \"http://\") || strings.HasPrefix(v, \"https://\")\n}","tryCatchPattern":"if _, err := localfileio.SafeLocalFlagPath(\"--file\", v); err != nil {\n    var pathErr *os.PathError\n    if errors.As(err, &pathErr) { /* fix path */ }\n    return fmt.Errorf(\"%w (allowed roots: cwd, /tmp, ~/files)\", err)\n}","preventionTips":["Keep input files inside cwd, /tmp, or ~/files","Use http(s) URLs for remote content, local paths otherwise","Avoid Windows-style paths on Unix and vice versa"],"tags":["validation","path","flag","policy"],"backgroundTag":"path-outside-allowlist","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}