Skip to content

Error in tool execution: Strings must be encoded before hashing (incl. fix) #642

Description

@ekr1

Issue

This is a bug in v1.0.5 because I cannot run later versions due to unrelated issues. Hence just text and no PR; it may not be relevant anymore.

agent> Try "echo" to see if you can start shell commands.
20k ◇ 0.0% ↑ 48 ↓ 20k ◇ 0.0% ↑↓
Tool Call: Local • Command
Command:
echo hello
Tool errors. Try again:
20k ◇ 0.0% ↑ 56 ↓ 40k ◇ 0.0% ↑↓
Tool Call: Local • Command
Options: timeout=10s
Command:
echo hello
Shell broken. `Local--Command` fail both times: `Error in tool execution: Strings must be encoded before hashing`.
Bug in tool wrapper, not command. Cannot start shell commands now.
21k ◇ 0.0% ↑ 39 ↓ 61k ◇ 0.0% ↑↓
21k ◇ 0.0% ↑ 86 ↓ 82k ◇ 0.0% ↑↓
Tool Call: Local • Orchestrate
Code:
cmd = Agent.get_tool("Local--Command")
r = await cmd.call(command="echo hello", timeout=10)
print(Agent.peek(r))
Orchestration execution error: Strings must be encoded before hashing
Traceback (most recent call last):
File "/Users/me/Documents/src/cecli-fork/cecli/helpers/orchestration/environment.py", line 514, in execute
result = await runner_coro
^^^^^^^^^^^^^^^^^
File "<agent_env>", line 2, in __agent_async_runner
File "/Users/me/Documents/src/cecli-fork/cecli/helpers/orchestration/tool_proxy.py", line 155, in call
result = await result
^^^^^^^^^^^^
File "/Users/me/Documents/src/cecli-fork/cecli/tools/command.py", line 185, in execute
confirmed = await cls._get_confirmation(coder, command, background)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/me/Documents/src/cecli-fork/cecli/tools/command.py", line 220, in _get_confirmation
command_hash = cls._hash_command(command_string)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/me/Documents/src/cecli-fork/cecli/tools/command.py", line 111, in _hash_command
return xxhash.xxh64(command).hexdigest()
^^^^^^^^^^^^^^^^^^^^^
TypeError: Strings must be encoded before hashing

It is fixed by this diff:

diff --git a/cecli/helpers/background_commands.py b/cecli/helpers/background_commands.py
index 47d4e1c41..6a5d86864 100644
--- a/cecli/helpers/background_commands.py
+++ b/cecli/helpers/background_commands.py
@@ -5,6 +5,7 @@ Provides a static BackgroundCommandManager class for running shell commands
in the background and capturing their output for injection into chat streams.
"""
+import hashlib
import os
import platform
import subprocess
@@ -419,7 +420,8 @@ class BackgroundCommandManager:
Unique command key
"""
with cls._lock:
- key = f"bg_{cls._next_id}_{hash(command) % 10000:04d}"
+ digest = int.from_bytes(hashlib.sha256(command.encode("utf-8")).digest()[:4], "big")
+ key = f"bg_{cls._next_id}_{digest % 10000:04d}"
cls._next_id += 1
return key
diff --git a/cecli/tools/command.py b/cecli/tools/command.py
index 6a9b762e2..3712fcd5c 100644
--- a/cecli/tools/command.py
+++ b/cecli/tools/command.py
@@ -108,7 +108,7 @@ class Tool(BaseTool):
if not command:
return command
- return xxhash.xxh64(command).hexdigest()
+ return xxhash.xxh64(command.encode("utf-8")).hexdigest()
@classmethod
async def execute(

Version and model info

cecli v1.0.5.dev+less
Models claude-opus-4.8 (main) • claude-haiku-4.5 (weak)
Settings agent (edit format) • 2k think tokens • infinite output
Environment .git (2,373 files) • Warning: For large repos, consider using --subtree-only and .cecli.ignore •
map (4096 tokens, auto refresh)
├─ Subagents memorizer • worker
├─ Skills caveman
└─ Servers Local

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions