How Security Features in Instagit Handle Blocked or Rejected Requests

Instagit detects blocked requests by scanning API responses for the phrase "security validation" in short responses, immediately aborting the operation and bypassing retry logic to prevent silent failures.

The instalabsAI/instagit repository implements a dedicated security-validation layer that monitors backend API responses in real time. When the system encounters a policy block or security rejection, it halts execution instantly rather than attempting retries. This article examines the specific security features in Instagit that handle blocked or rejected requests, tracing the implementation from stream detection to client-side error surfacing.

How Instagit Detects Security Rejections

Instagit identifies security blocks by analyzing the complete text returned from the backend API after streaming concludes. The detection relies on two specific indicators: response length and content markers.

Streaming Response Collection in api.ts

During API communication, Instagit collects all Server-Sent Events (SSE) stream fragments into a single string variable called collectedText. This accumulation happens inside the streaming loop defined in src/api.ts, ensuring the entire response payload is available for inspection once the stream terminates.

After the stream ends, the code passes collectedText to the security validation helper before proceeding with normal processing.

The isSecurityRejection Helper in retry.ts

The core detection logic resides in src/retry.ts within the isSecurityRejection() function (lines 31-33). This helper implements a strict heuristic to distinguish security blocks from legitimate responses:

export function isSecurityRejection(text: string): boolean {
  // Short responses containing "security validation" indicate a block
  return text.length < 100 && text.toLowerCase().includes("security validation");
}

The function returns true only when both conditions are met: the response contains fewer than 100 bytes and includes the phrase "security validation" (the specific marker used by the Instagit backend to signal policy violations). This dual-check prevents false positives from long error messages that might coincidentally contain similar words.

Handling Blocked Requests Without Retry Loops

Once Instagit identifies a security rejection, it treats the error as fatal rather than transient. This design prevents the system from wastefully retrying requests that will never succeed due to policy violations.

Immediate Abort in api.ts

When isSecurityRejection() returns true, the code in src/api.ts (lines 173-176) immediately throws a descriptive error:

// After the SSE stream ends, check for a permanent security rejection
if (isSecurityRejection(collectedText)) {
  // The backend flagged the request (e.g., disallowed content)
  throw new Error(`Request blocked: ${collectedText.slice(0, 200)}`);
}

The error message includes the prefix Request blocked: followed by a truncated excerpt of the backend response, providing immediate context about why the request failed.

Fatal Error Classification

The error handling logic in src/api.ts (lines 92-95) specifically checks for this prefix to bypass the standard retry mechanism:

// If the backend blocked the request, don't retry
if (error.message?.startsWith("Request blocked:")) {
  throw error; // Fatal error, no retry
}

By re-throwing the error immediately without entering the retry loop, Instagit ensures that blocked requests fail fast. This prevents the system from hammering the backend with repeated attempts that violate security policies, reducing unnecessary network traffic and latency.

Surfacing Security Errors to Clients

The final layer of Instagit's security handling ensures that end users receive clear, actionable error messages when their requests are blocked.

MCP Tool Implementation in index.ts

In src/index.ts, the MCP (Model Context Protocol) tool implementation wraps the API call and catches security-specific errors:

try {
  result = await callApi(token);
} catch (err: unknown) {
  const error = err as Error & { status?: number };
  // If the backend blocked the request, forward the error to the client
  if (error.message?.startsWith("Request blocked:")) {
    return { content: [{ type: "text", text: error.message }] };
  }
  // …other error handling…
}

When a blocked request is detected, the tool returns a structured response containing the exact error message, ensuring that the client application can display the security rejection to the user without modification or masking.

Summary

Instagit implements a multi-layered security validation system to handle blocked or rejected requests:

  • Detection: The isSecurityRejection() function in src/retry.ts identifies security blocks by checking for responses under 100 bytes containing the phrase "security validation".
  • Immediate Abort: Upon detection, src/api.ts throws a Request blocked: error and bypasses all retry logic to prevent wasteful reattempts.
  • Client Transparency: The MCP tool in src/index.ts catches these specific errors and surfaces them directly to users, ensuring clear communication of policy violations.

Frequently Asked Questions

How does Instagit differentiate between security rejections and temporary errors?

Instagit uses the isSecurityRejection() helper in src/retry.ts to apply a specific heuristic: the response must be shorter than 100 bytes and contain the lowercase phrase "security validation". Temporary network errors or server failures typically return different status codes or longer error messages, so they fail this check and proceed to the standard retry logic instead of immediate termination.

What happens if a blocked request error occurs during streaming?

The security check occurs after the SSE stream completes, once all text fragments have been concatenated into collectedText. If the backend sends a security rejection mid-stream, Instagit continues collecting the remaining stream data until the connection closes. Only then does it evaluate the complete response and throw the Request blocked: error, ensuring no partial data is processed as valid output.

Can the security validation detection be customized or disabled?

The detection parameters are hardcoded in the isSecurityRejection() function within src/retry.ts. The 100-byte threshold and the "security validation" keyword are not exposed as configuration options. To modify these behaviors, developers would need to edit the source code directly and rebuild the application, as there are no runtime flags or environment variables to adjust the security detection logic.

Where should developers look to modify the blocked request handling behavior?

To change how blocked requests are detected, examine src/retry.ts and modify the isSecurityRejection() function. To alter the error handling or retry bypass logic, edit the conditional checks in src/api.ts around lines 92-95 and 173-176. To customize how errors are presented to end users, modify the error handling block in src/index.ts where it checks for messages starting with "Request blocked:".

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →