Tencent/WeKnora · warning
path %q is not a valid file path
Error message
path %q is not a valid file path
What it means
resolveSkillFilePath rejects a requested path containing a NUL byte (strings.ContainsRune(trimmed, 0)), since NUL is illegal in filesystem paths and typically signals corrupt or injected input. The error echoes the original requested path quoted for debugging.
Source
Thrown at internal/agent/tools/skill_file.go:398
// resolveSkillFilePath turns a model-supplied path into an absolute path
// proven to sit inside skillDir.
//
// A relative path is resolved against skillDir, which is what the model
// reaches for after being told the directory once. Everything is then cleaned
// and re-checked against the prefix, so "..", a symlink-looking spelling or an
// absolute path into a neighbouring skill all fail here rather than reaching
// the image. The directory itself is refused: it is not a file.
func resolveSkillFilePath(skillDir, requested string) (string, error) {
dir := path.Clean(strings.TrimSpace(skillDir))
if dir == "" || dir == "." || dir == "/" {
return "", fmt.Errorf("this tool is not bound to a skill directory")
}
trimmed := strings.TrimSpace(requested)
if trimmed == "" {
return "", fmt.Errorf("path is required; write a file inside %s", dir)
}
if strings.ContainsRune(trimmed, 0) {
return "", fmt.Errorf("path %q is not a valid file path", requested)
}
candidate := trimmed
if !path.IsAbs(candidate) {
candidate = path.Join(dir, candidate)
}
clean := path.Clean(candidate)
if clean == dir || !strings.HasPrefix(clean, dir+"/") {
return "", fmt.Errorf(
"path %q is outside this install's skill directory (%s); "+
"an install may only write its own skill",
requested, dir,
)
}
return clean, nil
}
View on GitHub (pinned to 988cbb0330)
Solutions
- Strip or reject NUL bytes from the path before calling Execute.
- Sanitize model-provided paths with a whitelist of allowed characters.
- Log and flag the request as suspicious if NUL bytes appear, since it likely indicates injection.
Example fix
// before
p := strings.ReplaceAll(rawPath, "\x00", "") // silently kept going, or passed raw
// after
if strings.ContainsRune(rawPath, 0) {
return errors.New("path contains NUL byte; rejecting")
}
in := SkillFileInput{Path: rawPath, Content: content} Defensive patterns
Strategy: validation
Validate before calling
if strings.ContainsRune(input.Path, 0) {
return errors.New("path contains NUL byte; rejecting input")
} Type guard
func isCleanPath(p string) bool { return !strings.ContainsRune(p, 0) && strings.TrimSpace(p) != "" } Try / catch
if _, err := tool.Execute(ctx, input); err != nil && strings.Contains(err.Error(), "not a valid file path") {
// sanitize or drop the request; treat as suspicious input
} Prevention
- Sanitize all model-provided paths against a character whitelist
- Treat NUL bytes as an injection signal and log/alert on them
- Avoid building paths from binary or C-string data without decoding checks
When it happens
Trigger: Calling Execute with a path argument that embeds a "\x00" character, usually from binary/corrupt data or deliberate path-traversal probing rather than normal model output.
Common situations: Adversarial prompt injection attempting filesystem tricks; binary payloads accidentally concatenated into a path string; upstream decoding bugs producing NUL-terminated C-string artifacts.
Related errors
- join request not found
- failed to retrieve: %s
- opensearch: index not found
- 2201
- opensearch: authentication failed
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/92e0e3b68329681e.
Report an issue: GitHub.