larksuite/cli · error
%s must be an absolute path, got %q
Error message
%s must be an absolute path, got %q
What it means
SafeEnvDirPath validates an environment-provided application directory and requires the Cleaned value to be an absolute path. Relative paths are ambiguous across processes and working directories, so the function rejects them with the environment variable name and offending value.
Source
Thrown at internal/vfs/localfileio/path.go:132
return value, nil
}
if _, err := SafeInputPath(value); err != nil {
return "", fmt.Errorf("%s: %w", flagName, err)
}
return value, nil
}
// SafeEnvDirPath validates an environment-provided application directory path.
// It requires an absolute path, rejects control characters, normalizes the
// input, and resolves symlinks through the nearest existing ancestor.
func SafeEnvDirPath(path, envName string) (string, error) {
if err := charcheck.RejectControlChars(path, envName); err != nil {
return "", err
}
path = filepath.Clean(path)
if !filepath.IsAbs(path) {
return "", fmt.Errorf("%s must be an absolute path, got %q", envName, path)
}
resolved, err := resolveNearestAncestor(path)
if err != nil {
return "", fmt.Errorf("cannot resolve symlinks: %w", err)
}
return resolved, nil
}
// safePath is the shared implementation for SafeOutputPath and SafeInputPath.
// A path is accepted when its real location falls inside the built-in
// allowlist (cwd, /tmp, ~/files) and outside the built-in denylist; deny wins
// over allow, cwd included. Both lists are compiled in (policy.go), which
// also documents the two bounded environment inputs that remain.
func safePath(raw, flagName string) (string, error) {
isOutputFlag := flagName == "--output"
if err := charcheck.RejectControlChars(raw, flagName); err != nil {
return "", errView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Set the environment variable to an absolute path: /home/user/mydir
- Expand ~ yourself (or use $HOME) before setting the variable
- Prefix with $(pwd) in shell when constructing the value at runtime
Example fix
# before export LARK_APP_DIR=./myapp # error: LARK_APP_DIR must be an absolute path, got "myapp" # after export LARK_APP_DIR="$PWD/myapp"
Defensive patterns
Strategy: validation
Validate before calling
if !filepath.IsAbs(filepath.Clean(v)) {
return fmt.Errorf("%s must be absolute, got %q", envName, v)
} Type guard
func isAbsNoTilde(v string) bool {
return !strings.HasPrefix(v, "~") && filepath.IsAbs(filepath.Clean(v))
} Try / catch
dir, err := localfileio.SafeEnvDirPath(os.Getenv("MY_APP_DIR"), "MY_APP_DIR")
if err != nil {
return fmt.Errorf("fix the environment variable: %w", err)
} Prevention
- Set directory env vars with absolute paths ($PWD/mydir, not ./mydir)
- Remember ~ is not expanded in env values; use $HOME
- Validate .env and systemd Environment= values at startup
When it happens
Trigger: Calling SafeEnvDirPath with a relative value such as "mydir", "./mydir", or "~/files" (tilde is not expanded here) — typically from an env var like LARK_*_DIR set to a relative path, or a config template left unfilled.
Common situations: Env var set as `export APP_DIR=./data` in a script; a .env file with a relative default; a systemd unit with a relative Environment= value; user assuming ~ expansion happens.
Related errors
- local input path must not be empty
- local input path must not contain control characters
- %s: %w
- %s must not be empty
- Invalid column: {column!r}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/4617f8574bc8bdbd.
Report an issue: GitHub.