Skip to main content

File Operations

NullClaw provides four file operation tools with strict path security and workspace scoping:
  • file_read — Read file contents
  • file_write — Write or overwrite files
  • file_edit — Find and replace text
  • file_append — Append content to files
All file tools enforce:
  • Workspace scoping — operations restricted to workspace_dir by default
  • Absolute path support — with explicit allowed_paths configuration
  • Path traversal protection../ patterns blocked
  • Symlink validation — links validated after resolution
  • System path blocklist — sensitive paths like /etc/passwd rejected

file_read

Read file contents with size limits and path validation.

Parameters

string
required
Relative path to the file within the workspace

Configuration

Usage

Response:

Error Cases

  • File not found — Returns failure with “Failed to resolve file path”
  • Path traversal — Returns “Path not allowed: contains traversal or absolute path”
  • Outside workspace — Returns “Path is outside allowed areas”
  • File too large — Returns “File too large: X bytes (limit: Y bytes)”
  • Missing parameter — Returns “Missing ‘path’ parameter”

Absolute Path Support

To read files outside the workspace:
Then read absolute paths:
Absolute paths without allowed_paths configuration are rejected with: “Absolute paths not allowed (no allowed_paths configured)“

Source

src/tools/file_read.zig:13-91

file_write

Write contents to a file with atomic temp+rename for hard link safety.

Parameters

string
required
Relative path to the file within the workspace
string
required
Content to write to the file

Configuration

Usage

Response:

Behavior

  • Creates parent directories — Automatically creates missing parent dirs
  • Overwrites existing files — Replaces content atomically
  • Preserves executable mode — On Unix, preserves file mode (e.g., 0755)
  • Symlink-aware — Writes to canonical target, preserving symlink
  • Hard link isolation — Uses temp+rename to avoid mutating other inodes

Atomic Write Strategy

To prevent partial writes and hard link side effects:
  1. Create temp file .nullclaw-write-{timestamp}-{attempt}.tmp
  2. Write content to temp file
  3. Preserve file mode from existing file (if any)
  4. Rename temp file to target (atomic inode swap)
  5. Validate final path is within allowed areas
  6. Clean up on failure
Existing symlink:
Write to link.txt → writes to target.txt, preserves symlink Symlink escape prevention:
Write to escape.txtrejected (target outside workspace) Without hard link protection:
With temp+rename (NullClaw):

Source

src/tools/file_write.zig:11-222

file_edit

Find and replace the first occurrence of text in a file.

Parameters

string
required
Relative path to the file within the workspace
string
required
Text to find in the file (must be non-empty)
string
required
Replacement text (can be empty to delete)

Configuration

Usage

Response:

Behavior

  • First occurrence only — Replaces only the first match
  • Exact match required — Text must match exactly (case-sensitive)
  • Empty new_text — Deletes old_text
  • Empty old_text — Rejected with “old_text must not be empty”
  • No match — Returns failure “old_text not found in file”

Example: Multiple replacements

File: config.toml
Edit:
Result:
For global find-replace, call file_edit multiple times or use shell with sed.

Source

src/tools/file_edit.zig:13-116

file_append

Append content to the end of a file (creates file if missing).

Parameters

string
required
Relative path to the file within the workspace
string
required
Content to append to the file

Configuration

Usage

Append to existing file:
Response:
Create new file:
Response:

Behavior

  • Creates file if missing — No error if file doesn’t exist
  • Reads existing content — Loads existing file first
  • Concatenates — Appends new content to end
  • Writes atomically — Truncate+write ensures consistency
  • Validates new files — Ensures created files are within allowed areas

Use Cases

Log file:
Multi-append:
Concurrent appends are not atomic. Use locking or sequential writes for multi-agent scenarios.

Source

src/tools/file_append.zig:18-124

Path Security

workspace_only Mode

By default, all file tools are restricted to workspace_dir:
Allowed:
  • src/main.zig/workspace/src/main.zig
  • data/input.json/workspace/data/input.json
  • ./file.txt/workspace/file.txt
Blocked:
  • /etc/passwd → “Absolute paths not allowed”
  • ../../../etc/passwd → “Path not allowed: contains traversal”
  • src/../../../etc/passwd → “Path is outside allowed areas” (resolved)

Absolute Path Support

With allowed_paths configuration:
Allowed:
  • src/main.zig/workspace/src/main.zig (workspace)
  • /data/input.json/data/input.json (allowed_paths)
  • /home/user/configs/app.yaml → allowed
Blocked:
  • /etc/passwd → “Path is outside allowed areas”
  • /tmp/file.txt → “Path is outside allowed areas”

Path Resolution

All paths are resolved with realpathAlloc() to:
  • Canonicalize paths (remove . and ..)
  • Follow symlinks to final destination
  • Validate against workspace + allowed_paths
Example:
Read link → resolves to /etc/passwdrejected

System Blocklist

The following paths are always blocked by isResolvedPathAllowed():
  • /etc/* (except on macOS where some system paths are safe)
  • /var/run/*
  • /sys/*
  • /proc/*
  • /dev/*

Null Byte Injection

Paths containing null bytes are rejected:
Response:

Testing

All file tools include comprehensive test coverage in src/tools/file_*.zig:
  • Basic operations — read, write, edit, append
  • Path security — traversal, symlinks, hard links
  • Error cases — missing files, missing params
  • Absolute paths — with/without allowed_paths
  • Edge cases — empty files, empty content, UTF-8 boundaries
Run tests:
Test count: 3,371 tests across entire codebase