Tencent/WeKnora · error

failed to read script for validation: %w

Error message

failed to read script for validation: %w

What it means

runScriptValidation reads the script file from disk when config.ScriptContent is empty and config.Script is set, so security validation can inspect the source. If os.ReadFile fails (missing file, permission denied, path is a directory), the OS error is wrapped as "failed to read script for validation: %w" and Execute aborts before running anything.

Source

Thrown at internal/sandbox/manager.go:122

	return sandbox.Execute(ctx, effective)
}

// runScriptValidation is the package-level helper that DefaultManager and
// SessionBoundManager share for pre-execution security checks. Extracting
// it avoids duplicating the same script/args/stdin validation logic across
// two Manager implementations while keeping the ScriptValidator private to
// the manager that owns it.
func runScriptValidation(validator *ScriptValidator, config *ExecuteConfig) error {
	if validator == nil || config == nil {
		return nil
	}

	// Get script content for validation
	scriptContent := config.ScriptContent
	if scriptContent == "" && config.Script != "" {
		content, err := os.ReadFile(config.Script)
		if err != nil {
			return fmt.Errorf("failed to read script for validation: %w", err)
		}
		scriptContent = string(content)
	}

	// Validate script content
	if scriptContent != "" {
		result := validator.ValidateScript(scriptContent)
		if !result.Valid {
			for _, verr := range result.Errors {
				log.Printf("[sandbox] Validation error: %s", verr.Error())
			}
			if len(result.Errors) > 0 {
				return result.Errors[0]
			}
			return ErrSecurityViolation
		}
	}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Verify the path in config.Script exists and is readable (os.Stat beforehand).
  2. Embed the code directly in config.ScriptContent so no file read is needed.
  3. Fix file permissions or container volume mounts so the process can read the script.
  4. Use an absolute path or resolve relative to the correct working directory.

Example fix

// before
cfg.Script = "scripts/run.py" // file missing
// after
if _, err := os.Stat(cfg.Script); err != nil { return err }
cfg.ScriptContent = string(scriptBytes) // or fix the path/permissions
Defensive patterns

Strategy: validation

Validate before calling

if cfg.ScriptContent == "" && cfg.Script != "" {
    if _, err := os.Stat(cfg.Script); err != nil {
        return fmt.Errorf("script file unreadable: %w", err)
    }
}

Try / catch

res, err := mgr.Execute(ctx, execCfg)
if err != nil && strings.Contains(err.Error(), "failed to read script") {
    return fmt.Errorf("check config.Script path %q: %w", execCfg.Script, err)
}

Prevention

When it happens

Trigger: Calling Execute with a config that leaves ScriptContent empty and sets Script to a path that does not exist, is unreadable (permissions), or is a directory.

Common situations: Passing a path relative to a different working directory than the process; container/deployment where the script file was not copied; wrong file permissions after mounting a volume; typo in the script filename; deleting the temp script before Execute runs.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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