Skip to content

SDK migration

Our philosophy around major SDK version upgrades is to avoid breaking changes where possible. When they are necessary, we deprecate rather than break, and provide a clear migration path that remains supported for some time.

This page documents breaking changes and migrations between SDK releases.

The JS SDK on main includes the following breaking changes.

Remove threshold and score from prompt injection detection

Section titled “Remove threshold and score from prompt injection detection”

detectPromptInjection({ threshold }) and ArcjetPromptInjectionReason.score are removed. Only mode remains.

The verdict is binary. Use decision.reason.isPromptInjection() or decision.reason.injectionDetected:

detectPromptInjection({ mode: "LIVE" });
if (decision.reason.isPromptInjection()) {
return new Response("Prompt injection detected", { status: 403 });
}

Drop threshold and score when you upgrade. The core SDK ignores leftover threshold – it does not throw and it does not change the rule id.

@arcjet/astro validates rule options with Zod .strict(). Leftover threshold in the integration config throws at startup. Remove threshold from astro.config when you upgrade.

This change applies to the JS SDK only.

The Python SDK on main includes the following breaking changes.

Remove threshold from prompt injection detection

Section titled “Remove threshold from prompt injection detection”

detect_prompt_injection(threshold=...) and the threshold field on PromptInjectionDetection are removed. Only mode remains, and it is required.

from arcjet import Mode, detect_prompt_injection
detect_prompt_injection(mode=Mode.LIVE)

Drop threshold when you upgrade to Python SDK main. Passing threshold= raises TypeError. This differs from the JS core SDK, which ignores leftover threshold and does not throw. @arcjet/astro Zod .strict() throws at startup if threshold is still in the integration config.

PromptInjectionReason.score remains deprecated. This removal does not drop score.

Require explicit mode on HTTP rule factories

Section titled “Require explicit mode on HTTP rule factories”

HTTP Protect rule factories require mode. Omitting it raises TypeError. Pass mode on every shield(), detect_bot(), token_bucket(), fixed_window(), sliding_window(), validate_email(), detect_sensitive_info(), filter_request(), and detect_prompt_injection() call.

from arcjet import Mode, detect_bot, shield
rules = [
shield(mode=Mode.LIVE),
detect_bot(mode=Mode.LIVE, allow=["CATEGORY:SEARCH_ENGINE"]),
]

protect_signup() forwards its nested rate_limit, bots, and email mappings to those factories, so each mapping must include mode too.

This differs from JavaScript HTTP rules, which default to "DRY_RUN". Defaulting Python HTTP rules to DRY_RUN turns LIVE configs into observe-only. Requiring mode is the breaking change.

Guard constructors still default to Mode.LIVE, matching the JavaScript Guard SDK. You can omit mode on Guard constructors.

These changes are on Python SDK main, not in published arcjet 0.9.0 or 0.10.0b1.

There have been no breaking changes.

The 1.0.0 version of the Arcjet JS SDK was released on January 22, 2026. No migrations are required from the last 1.0.0-beta-18 release.

The 1.0.0-beta-18 version of the Arcjet JS SDK was released on January 22, 2026 and includes the following breaking changes.

Reading streams has various pitfalls. You can now pass what value to check explicitly:

const decision = await arcjet.protect(request, { sensitiveInfoValue: "..." });

This value is processed locally and is not sent to the Arcjet cloud API.

If you use tools that patch request.body, such as body-parser, you are not affected and can continue to use them.

The 1.0.0-beta-17 version of the Arcjet JS SDK was released on January 13, 2026 and includes the following breaking changes.

Remove block field in validateEmail rule config

Section titled “Remove block field in validateEmail rule config”

This field was deprecated in 1.0.0-beta-1 in favor of deny:

validateEmail({ deny: ["DISPOSABLE"], mode: "LIVE" });

The 1.0.0-beta-1 version of the Arcjet JS SDK was released on January 15, 2025 and includes the following breaking changes.

When configuring the validateEmail rule we have renamed the block option to deny. This follows the same API design as the other rules.

validateEmail({
mode: "LIVE",
// replace block with deny as shown
// block: ["DISPOSABLE"],
deny: ["DISPOSABLE"],
});

It is now also possible to configure email types to allow. In the following example, Arcjet allows only email addresses from free email providers.

validateEmail({
mode: "LIVE",
allow: ["FREE"],
});

The old options continue to work, but are flagged as deprecated.

In earlier versions of the SDK we provided enum objects for configuring your rules. These have been deprecated in favor of string-type enums.

The following table shows which enums to replace and their equivalent strings.

alphabeta
ArcjetMode.LIVE"LIVE"
ArcjetMode.DRY_RUN"DRY_RUN"
ArcjetRateLimitAlgorithm.TOKEN_BUCKET"TOKEN_BUCKET"
ArcjetRateLimitAlgorithm.FIXED_WINDOW"FIXED_WINDOW"
ArcjetRateLimitAlgorithm.SLIDING_WINDOW"SLIDING_WINDOW"
ArcjetEmailType.DISPOSABLE"DISPOSABLE"
ArcjetEmailType.FREE"FREE"
ArcjetEmailType.NO_MX_RECORDS"NO_MX_RECORDS"
ArcjetEmailType.NO_GRAVATAR"NO_GRAVATAR"
ArcjetEmailType.INVALID"INVALID"
ArcjetStack.NODEJS"NODEJS"
ArcjetStack.NEXTJS"NEXTJS"
ArcjetStack.BUN"BUN"
ArcjetStack.SVELTEKIT"SVELTEKIT"
ArcjetStack.DENO"DENO"
ArcjetStack.NESTJS"NESTJS"
ArcjetStack.REMIX"REMIX"
ArcjetRuleState.RUN"RUN"
ArcjetRuleState.NOT_RUN"NOT_RUN"
ArcjetRuleState.CACHED"CACHED"
ArcjetRuleState.DRY_RUN"DRY_RUN"
ArcjetConclusion.ALLOW"ALLOW"
ArcjetConclusion.DENY"DENY"
ArcjetConclusion.CHALLENGE"CHALLENGE"
ArcjetConclusion.ERROR"ERROR"
ArcjetSensitiveInfoType.EMAIL"EMAIL"
ArcjetSensitiveInfoType.PHONE_NUMBER"PHONE_NUMBER"
ArcjetSensitiveInfoType.IP_ADDRESS"IP_ADDRESS"
ArcjetSensitiveInfoType.CREDIT_CARD_NUMBER"CREDIT_CARD_NUMBER"
ArcjetRuleType.LOCAL"LOCAL"
ArcjetRuleType.REMOTE"REMOTE"

URL-encoded data in sensitive info detection

Section titled “URL-encoded data in sensitive info detection”

Arcjet Sensitive info detection and @arcjet/redact features handle both raw and URL-encoded data simultaneously. This dual processing approach improves detection, particularly for content containing the + character, which serves both as a literal plus sign (common in phone numbers) and as an encoded space in URLs.

When implementing custom detection functions on data containing + characters, you may observe duplicate token matches across different processing windows. This occurs because the system analyzes the input in two ways:

  • With + interpreted as a literal plus sign
  • With + decoded as a space character

For example:

# Input: "phone+number+123"
# Processed as both:
# - "phone+number+123"
# - "phone number 123"

Wasm loading has moved to @arcjet/analyze-wasm

Section titled “Wasm loading has moved to @arcjet/analyze-wasm”

We have moved the responsibility for loading Wasm on your target platform from @arcjet/analyze to @arcjet/analyze-wasm. This does not affect users who were using the SDK through the high level framework adapters, such as @arcjet/next.

The 1.0.0-alpha-24 version of the Arcjet JS SDK was released on September 5, 2024 and includes the following breaking changes.

add and remove replaced with allow and deny in detectBot rule

Section titled “add and remove replaced with allow and deny in detectBot rule”

Passing user agent patterns to the bot detection rules has been deprecated in favor of specifying string-type enums to allow or deny.

To maintain the previous default behavior of denying all bots, you can configure the following rule:

detectBot({
mode: "LIVE",
allow: [],
});

We now publish a list of known bots as both individual user agents as well as categories of types of bots. You can use these to configure your bot detection rules.

For example, a common configuration is to block all bots except search engine crawlers:

detectBot({
mode: "LIVE",
// Block all bots except the following
allow: [
"CATEGORY:SEARCH_ENGINE", // Google, Bing, etc
// Uncomment to allow these other common bot categories
// See the full list at https://arcjet.com/bot-list
//"CATEGORY:MONITOR", // Uptime monitoring services
//"CATEGORY:PREVIEW", // Link previews e.g. Slack, Discord
],
}),

Need help with anything? Email us or join our Discord to get support from our engineering team.

Discussion