{"record":{"id":"8556fc6f8832b4a3","repo":"larksuite/cli","slug":"local-input-path-must-not-be-empty","errorCode":null,"errorMessage":"local input path must not be empty","messagePattern":"local input path must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/vfs/localfileio/path.go","lineNumber":62,"sourceCode":"// The baseline invariant asserted by drive sync, upload flags, and the CI\n// quality gates is \"reject everything outside the built-in allowlist\"\n// (cwd, /tmp, ~/files) — see safePath. Out-of-tree content still reaches\n// flags via stdin (\"-\").\nfunc SafeInputPath(path string) (string, error) {\n\treturn safePath(path, \"--file\")\n}\n\n// LocalInputPath validates an input path in the process local filesystem\n// namespace. It intentionally does not impose allowlist containment or\n// canonicalize the returned path: absolute paths, parent-relative paths, and\n// symlink traversal retain their normal OS semantics (the grandfathered\n// apps-upload exception, see #2005). The built-in denylist still applies:\n// even the relaxed tier may not reach protected directories. Character\n// validation remains mandatory because paths are user-controlled and may\n// appear in errors or progress output.\nfunc LocalInputPath(path string) (string, error) {\n\tif strings.TrimSpace(path) == \"\" {\n\t\treturn \"\", fmt.Errorf(\"local input path must not be empty\")\n\t}\n\tif strings.IndexFunc(path, unicode.IsControl) >= 0 {\n\t\treturn \"\", fmt.Errorf(\"local input path must not contain control characters\")\n\t}\n\tif err := charcheck.RejectControlChars(path, \"local input path\"); err != nil {\n\t\treturn \"\", err\n\t}\n\tif err := validateLocalInputPlatform(path); err != nil {\n\t\treturn \"\", err\n\t}\n\tif err := denyCheckLocalInput(path); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn path, nil\n}\n\n// denyCheckLocalInput applies the built-in denylist to the relaxed local\n// input tier. Resolution is fail-closed like safePath, but the allowlist is","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/vfs/localfileio/path.go#L44-L80","documentation":"LocalInputPath validates a user-supplied input path in the relaxed local tier and rejects a value that is empty or only whitespace before any other check. The tier returns the path verbatim, so an empty string could never name a real file and would only produce confusing downstream OS errors.","triggerScenarios":"Calling localfileio.LocalInputPath(\"\") or LocalInputPath(\"   \") — e.g. a --file flag value that was never populated, an unset config value, or a shell variable expanding to nothing.","commonSituations":"A shell variable like $FILE is empty because the producing command failed; a CI secret/variable not set; a script passing ${1:-} through; config file with an empty key.","solutions":["Populate the path argument before calling the API or command","Check that the producing variable/config key is actually set: `${FILE:?FILE not set}` in shell","Fail fast in your script if the value is empty before invoking the CLI"],"exampleFix":"// before\np, err := localfileio.LocalInputPath(cfg.FilePath)\n// after\nif strings.TrimSpace(cfg.FilePath) == \"\" {\n    return fmt.Errorf(\"--file is required\")\n}\np, err := localfileio.LocalInputPath(cfg.FilePath)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(p) == \"\" {\n    return errors.New(\"input file path is required\")\n}","typeGuard":"func nonEmptyPath(p string) (string, bool) {\n    p = strings.TrimSpace(p)\n    return p, p != \"\"\n}","tryCatchPattern":"p, err := localfileio.LocalInputPath(flagValue)\nif err != nil {\n    return fmt.Errorf(\"--file: %w\", err)\n}","preventionTips":["Use ${VAR:?msg} guards for path variables in shell","Fail fast on empty flag values at argument parsing time","Check upstream command exit codes before reusing their output as a path"],"tags":["validation","path","empty-input"],"backgroundTag":"empty-path-argument","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"}