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

  1. Strip or reject NUL bytes from the path before calling Execute.
  2. Sanitize model-provided paths with a whitelist of allowed characters.
  3. 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

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


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/92e0e3b68329681e. Report an issue: GitHub.