Skip to content

[fp-check] Stop hook returns non-JSON output causing JSON validation error in Claude Code #131

@AA8j

Description

@AA8j

Bug Description

The fp-check plugin's Stop hook produces output that fails JSON validation in Claude Code, causing the error: "JSON validation failed".

Environment

  • Plugin: fp-check (plugins/fp-check)
  • Plugin version: 1.0.0
  • Claude Code: Latest version
  • Plugin source: trailofbits/skills

Issue Details

When Claude Code attempts to stop or exit a session, the fp-check plugin's Stop hook runs and produces the following error:

Ran 2 stop hooks (ctrl+o to expand)
Stop hook error: JSON validation failed

Root Cause Analysis

The Stop hook in plugins/fp-check/hooks/hooks.json (lines 4-14) uses type: "prompt":

"Stop": [
  {
    "matcher": "*",
    "hooks": [
      {
        "type": "prompt",
        "prompt": "You are a verification completeness checker...If ANY bug is missing...return 'block'...return 'approve'.",
        "timeout": 30
      }
    ]
  }
]

The prompt instructs the LLM to return either 'approve' or 'block' as plain text. However, Claude Code's Stop hook mechanism expects JSON-formatted output with fields such as:

{"decision": "approve"}

or

{"decision": "block", "reason": "..."}

When the prompt hook returns plain text like approve or block (without JSON formatting), Claude Code's JSON parser fails because the output is not valid JSON.

Expected Behavior

The Stop hook should return valid JSON-formatted output that Claude Code can parse and interpret.

Suggested Fix

Modify the prompt in plugins/fp-check/hooks/hooks.json to instruct the LLM to return JSON-formatted output instead of plain text:

Change from:

If ANY bug is missing ANY of these phases or the gate review, return 'block' with the specific gaps.
If all bugs have complete verification with verdicts, return 'approve'.
If the conversation is not about fp-check verification at all, return 'approve'.

Change to:

If ANY bug is missing ANY of these phases or the gate review, return: {"decision": "block", "reason": "<specific gaps>"}
If all bugs have complete verification with verdicts, return: {"decision": "approve"}
If the conversation is not about fp-check verification at all, return: {"decision": "approve"}

The same fix should be applied to the SubagentStop hook (lines 16-26) which has the identical issue.

Impact

This error appears every time Claude Code attempts to stop/exit a session when the fp-check plugin is enabled, regardless of whether the fp-check skill was actively used during the session.

Reproduction Steps

  1. Install and enable the fp-check plugin from trailofbits/skills marketplace
  2. Start any Claude Code session
  3. Exit the session (via /exit or natural termination)
  4. Observe the "JSON validation failed" error for Stop hooks

Reported by Claude Code (claudecode)

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