larksuite/cli · error
unsafe --output-dir
Error message
unsafe --output-dir
What it means
errOutputDirUnsafe is a sentinel error for the --output-dir flag in cmd/event/consume.go. sanitizeOutputDir rejects directories that fail path safety checks (e.g. traversal, invalid paths) and call sites wrap it as a typed errs.ValidationError (SubtypeInvalidArgument, param --output-dir) that includes the underlying reason.
Source
Thrown at cmd/event/consume.go:450
if err != nil {
if _, ok := errs.ProblemOf(err); ok {
return "", err
}
return "", errs.NewAuthenticationError(errs.SubtypeTokenMissing,
"resolve tenant access token: %s", err).WithCause(err)
}
if result == nil || result.Token == "" {
return "", errs.NewAuthenticationError(errs.SubtypeTokenMissing,
"no tenant access token available for app %s", appID).
WithHint("check that app_secret is configured for this distribution")
}
return result.Token, nil
}
// Sentinels for errors.Is checks; call sites wrap them as typed ValidationError causes.
var (
errInvalidParamFormat = errors.New("invalid --param format") //nolint:forbidigo // sentinel, typed at call sites
errOutputDirUnsafe = errors.New("unsafe --output-dir") //nolint:forbidigo // sentinel, typed at call sites
)
func parseParams(raw []string) (map[string]string, error) {
m := make(map[string]string)
for _, kv := range raw {
k, v, ok := strings.Cut(kv, "=")
if !ok || k == "" {
return nil, errs.NewValidationError(errs.SubtypeInvalidArgument,
"%s %q: expected key=value", errInvalidParamFormat, kv).
WithParam("--param").
WithCause(errInvalidParamFormat)
}
m[k] = v
}
return m, nil
}
// watchStdinEOF drains r until EOF, writes a diagnostic, then cancels; only safe in non-TTY mode.View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Provide a simple, safe directory path without '..' or traversal segments (e.g. ./out or /tmp/events).
- Create the directory first if required and confirm you have write permission.
- Read the wrapped %s reason in the error to see which specific check failed.
- In scripts, sanitize the path (or use a fixed workspace-relative directory) before passing it.
Example fix
// before lark event consume --output-dir ../../etc // after lark event consume --output-dir ./out
Defensive patterns
Strategy: validation
Validate before calling
// shell pre-check before invoking the CLI
case "$outdir" in
*..*|""|/) echo "unsafe --output-dir: $outdir"; exit 1 ;;
esac
mkdir -p "$outdir" 2>/dev/null || { echo "cannot create $outdir"; exit 1; } Type guard
func looksSafeOutputDir(dir string) bool {
if dir == "" || strings.Contains(dir, "..") {
return false
}
return filepath.IsAbs(dir) || strings.HasPrefix(dir, "./") || !strings.ContainsRune(dir, ':')
} Try / catch
// Go caller of sanitizeOutputDir
safe, err := sanitizeOutputDir(dir)
if err != nil {
if errors.Is(err, errOutputDirUnsafe) {
// fall back to a default workspace-relative directory
safe, err = sanitizeOutputDir("./out")
}
if err != nil {
return err
}
} Prevention
- Use fixed workspace-relative output directories in scripts/CI.
- Never interpolate raw user input directly into --output-dir.
- Create the directory beforehand and confirm write permission.
- Avoid '..' and platform-specific path quirks in flag values.
When it happens
Trigger: Running event consume with --output-dir pointing to an unsafe path such as containing '..' traversal, an invalid/absolute path failing validation, or a path rejected by the path-safety check in sanitizeOutputDir.
Common situations: Scripts interpolating user input into the flag; relative paths that resolve outside the allowed root; copy-pasted Windows-style paths on POSIX hosts; CI templates with placeholder traversal segments.
Related errors
- invalid --param format
- unknown flag: --{name}
- path validation failed
- command set %d command %d: command path %q conflicts with %s
- command set %d command %d (%s): %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/e714fd46f05eef47.
Report an issue: GitHub.