Skip to content

Fix question tool version file written as null byte#48

Merged
mcintyre94 merged 4 commits intomcintyre94:mainfrom
zmanian:fix/question-tool-version-write
Mar 10, 2026
Merged

Fix question tool version file written as null byte#48
mcintyre94 merged 4 commits intomcintyre94:mainfrom
zmanian:fix/question-tool-version-write

Conversation

@zmanian
Copy link
Copy Markdown
Contributor

@zmanian zmanian commented Mar 7, 2026

Summary

  • The Sprites fs/write REST API corrupts very small file uploads -- the 1-byte version file ("3") was being written as a null byte (\0)
  • This caused the version check to always fail, triggering a reinstall loop that kept writing the same corrupt version file, blocking chat with "Claude question tool failed to install"
  • Fix: write the version file via exec (echo -n '3' > path) instead of the upload API; the server.py upload stays as-is since larger files work correctly

Hardening (new)

  • ExecSession now surfaces process exit codes via .exit(code:) event
  • runExec success means "exited 0 before timeout" instead of just "didn't time out"
  • Installation now fails properly if chmod/version-write step exits non-zero
  • Added follow-up verification that server.py is executable and version file matches before reporting success

Investigation

Verified on the bedrock-dev sprite:

  • server.py (3896 bytes) was uploaded correctly
  • version file contained a single null byte (\0) instead of "3"
  • Writing via echo -n '3' > file through exec produces the correct content

Test plan

  • Enable Claude Question Tool in Settings
  • Start a new chat on a sprite -- tool should install without error
  • Verify /home/sprite/.wisp/claude-question/version contains 3 (not a null byte)
  • Second chat should skip install (version matches)
  • Kill the sprite, start a new chat -- tool should reinstall cleanly
  • Verify exit code handling: runExec("false") returns success: false

Generated with Claude Code

The Sprites fs/write REST API corrupts very small file uploads,
writing a null byte instead of the version string "3". This caused
the version check to always fail, triggering a reinstall loop.

Write the version file via exec (echo -n) instead of the upload API.
The server.py upload is unaffected since larger files work correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mcintyre94
Copy link
Copy Markdown
Owner

That's a weird behaviour from that upload API, thanks for this! Hopefully it doesn't have similar issues for any of our other uploads.

zmanian and others added 3 commits March 7, 2026 08:46
- ExecSession now surfaces process exit codes via .exit(code:) event
- runExec success means "exited 0 before timeout" not just "didn't timeout"
- Claude question tool install fails properly if chmod/version-write fails
- Added follow-up verification that server.py is executable and version
  file matches before reporting success
- Work around fs/write API corrupting small payloads by using exec echo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The MCP tool installation was running eagerly in loadSession when the
view appeared, but the sprite may still be cold/warm at that point
causing exec commands to fail. Move installation to executeClaudeCommand
after service cleanup, when the sprite is guaranteed to be awake.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mcintyre94 mcintyre94 merged commit 0ee7bd8 into mcintyre94:main Mar 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants