Hmbown/CodeWhale · error
expected explicit block
Error message
expected explicit block
What it means
Test assertion message from explicit_message_denial_never_copies_raw_process_diagnostics: the hook executor was expected to emit an explicit structured denial block (sanitized reason) but did not. The test verifies that when a hook command denies a message submit, raw process diagnostics (stdout/stderr containing secrets like tokens and private paths) are never copied into the denial payload; this error means sanitization/structure regressed.
Solutions
- Run the test and inspect the actual denial payload produced by the HookExecutor
- Ensure the denial path emits an explicit block with the hook's stated reason only
- Verify stdout/stderr of the denied process are not forwarded verbatim (the fixture plants a token and private paths to catch leaks)
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at crates/tui/src/hooks/executor.rs:5583 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/30493c0a15c16faa.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/hooks/executor.rs:5583
assert_eq!(payload["turn_id"], "turn_test");
}
#[cfg(unix)]
#[test]
fn explicit_message_denial_never_copies_raw_process_diagnostics() {
let dir = tempfile::tempdir().expect("tempdir");
let command = r#"printf '%s\n' '{"reason":"blocked /Users/alice/private --run token=SUPERSECRET"}'; printf '%s\n' 'stderr-secret /tmp/private' >&2; exit 2"#;
let executor = HookExecutor::new(
HooksConfig {
enabled: true,
hooks: vec![Hook::new(HookEvent::MessageSubmit, command)],
..HooksConfig::default()
},
dir.path().to_path_buf(),
);
let outcome = executor.execute_message_submit_transform(&HookContext::new(), "hello");
let MessageSubmitOutcome::Blocked { reason } = outcome else {
panic!("expected explicit block");
};
assert_eq!(reason, "blocked [path] [argument] [secret]");
for secret in ["alice", "SUPERSECRET", "stderr-secret", "/tmp/private"] {
assert!(!reason.contains(secret), "leaked {secret}: {reason}");
}
}
#[cfg(unix)]
#[test]
fn foreground_pipe_capture_is_bounded_while_verbose_child_is_drained() {
let hook = Hook::new(
HookEvent::SessionStart,
"head -c 200000 /dev/zero | tr '\\0' o; head -c 200000 /dev/zero | tr '\\0' e >&2",
)
.with_timeout(5);
let executor = HookExecutor::new(HooksConfig::default(), PathBuf::from("."));
let result = executor.execute_sync(&hook, &HashMap::new());
assert!(result.success, "{:?}", result.error);View on GitHub (pinned to 433685b202)