What Is ParamError Validation and How Does It Act as a Client-Side Guard for Destructive Operations?
ParamError is a custom TypeError subclass that validates function arguments before any API call is made, blocking malformed requests that could trigger destructive or unintended server-side operations.
In the TencentDB Agent Memory SDK, ParamError validation serves as the first line of defense against bad inputs. Rather than letting invalid data reach the server—where it might cause 422 Unprocessable Entity errors, silent failures, or accidental data deletion—the SDK enforces strict parameter checks at the client level. This article breaks down how ParamError works, where it's implemented, and why it matters for operations like deleteAtomic and clearChatMemory.
What Is ParamError?
ParamError extends JavaScript's native TypeError to provide SDK-specific validation messaging. It's defined in the core errors module and thrown whenever input constraints are violated.
- Source location: [
sdk/memory-core/typescript/src/errors.ts](https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/feat/server_team/sdk/memory-core/typescript/src/errors.ts#L5-L8) - Base class:
TypeError - Purpose: Immediate, descriptive failures for invalid arguments
Unlike generic errors, ParamError includes contextual messages that identify exactly which parameter failed validation and why.
How ParamError Guards Destructive Operations
Destructive operations—methods that delete, clear, or permanently modify data—receive the most rigorous validation. The SDK refuses to execute these calls unless all required identifiers are present and properly formatted.
deleteAtomic: Preventing Empty Deletion Requests
The deleteAtomic method removes log entries by ID. Before issuing the HTTP request, the client validates that the ids array contains at least one element:
// sdk/memory-core/typescript/src/v3/client.ts
if (!ids || ids.length === 0) {
throw new ParamError("deleteAtomic requires a non-empty ids list");
}
Source: client.ts#L307-L308
Without this guard, an empty ids array might reach the server and either fail silently or delete unintended records depending on API implementation. The client-side check guarantees the operation has explicit targets.
clearChatMemory: Protecting Conversation History
The clearChatMemory method wipes chat memory for specified IDs. Similar to deleteAtomic, it requires a non-empty memory_ids list:
// sdk/memory-core/typescript/src/v3/client.ts
if (!memory_ids || memory_ids.length === 0) {
throw new ParamError("clearChatMemory requires a non-empty memory_ids list");
}
Source: client.ts#L391-L392
This validation prevents accidental bulk deletions caused by empty arrays or undefined variables in calling code.
Core Validation Patterns in the SDK
Beyond destructive operations, ParamError enforces consistent input standards across the entire client surface.
Required String Fields
API keys, endpoint URLs, and service identifiers must be non-empty strings before any request initialization:
// sdk/memory-core/typescript/src/v3/http.ts
if (!apiKey?.trim()) {
throw new ParamError("apiKey must be provided");
}
if (!endpoint?.trim()) {
throw new ParamError("endpoint must be provided");
}
Source: http.ts#L24-L28
These checks run during HttpClient construction, catching configuration errors before any network activity occurs.
Complex Field Combinations
Some operations require specific parameter groupings. The MemoryPromptClient validates that team_id accompanies agent_ids when both are used:
// sdk/memory-core/typescript/src/v3/memory-prompt-client.ts
if (agent_ids && !team_id) {
throw new ParamError("team_id is required with agent_ids");
}
Source: memory-prompt-client.ts#L35-L37
Array Content Validation
Beyond checking array length, the SDK validates that array elements themselves meet constraints:
// sdk/memory-core/typescript/src/v3/memory-prompt-client.ts
if (!agent_ids.every(id => typeof id === "string" && id.length > 0)) {
throw new ParamError("agent_ids must be a non-empty list of non-empty strings");
}
Source: memory-prompt-client.ts#L37-L38
Runtime Code Examples
TypeScript: Catching Configuration Errors
import { MemoryClient, ParamError } from "memory-core";
// Missing API key — fails immediately at client construction
try {
const client = new MemoryClient({
apiKey: "", // ← empty string triggers ParamError
serviceId: "svc-001"
});
} catch (e) {
if (e instanceof ParamError) {
console.error(e.message); // "apiKey must be provided"
}
}
TypeScript: Preventing Empty Deletion Calls
const client = new MemoryClient({
apiKey: process.env.API_KEY!,
serviceId: "svc-001"
});
// Attempting to delete with empty array — blocked before HTTP request
try {
await client.deleteAtomic({ ids: [] });
} catch (e) {
if (e instanceof ParamError) {
console.error(e.message); // "deleteAtomic requires a non-empty ids list"
}
}
// Valid usage proceeds to server
await client.deleteAtomic({ ids: ["log-abc123", "log-def456"] });
Python SDK Equivalent
The Python implementation mirrors TypeScript's validation strategy with a custom ParamError exception:
from tencentdb_agent_memory.v3 import MemoryClient, ParamError
client = MemoryClient(api_key="sk-...", service_id="svc-001")
# Empty list triggers ParamError immediately
try:
client.delete_atomic(ids=[])
except ParamError as e:
print(str(e)) # "deleteAtomic requires a non-empty ids list"
# Valid call proceeds to API
client.delete_atomic(ids=["log-abc123", "log-def456"])
Source: client.py#L67-L82
Why Client-Side Guarding Matters
| Benefit | Explanation |
|---|---|
| Zero network cost for invalid calls | Errors surface in milliseconds rather than after round-trip latency |
| Clear developer feedback | Specific messages pinpoint exact parameter failures |
| Accident prevention | Destructive operations require explicit, validated inputs |
| API contract hygiene | Server receives only well-formed, expected payloads |
| Cross-language consistency | TypeScript and Python SDKs enforce identical rules |
Key Implementation Files
Summary
- ParamError is a TypeError subclass that provides immediate, descriptive failures for invalid SDK inputs.
- Destructive operations like
deleteAtomicandclearChatMemoryrequire non-empty identifier lists—empty arrays triggerParamErrorbefore any HTTP request. - Validation occurs at multiple layers: HTTP client construction, method-specific checks, and complex field combination rules.
- Both TypeScript and Python SDKs implement identical guard logic, ensuring consistent behavior across languages.
- Client-side guarding eliminates wasted network calls, prevents accidental data loss, and delivers clear debugging information.
Frequently Asked Questions
What happens if I pass null instead of an empty array to deleteAtomic?
ParamError will still trigger. The validation checks !ids || ids.length === 0, so null, undefined, or [] all raise "deleteAtomic requires a non-empty ids list".
Can I disable ParamError validation for testing purposes?
No—the validation is hardcoded into client methods. This is by design: destructive operations should never execute without explicit, validated inputs. For testing, pass valid identifiers pointing to disposable test resources.
How does ParamError differ from standard TypeError?
ParamError extends TypeError but adds SDK-specific messaging and can be distinguished using instanceof ParamError. This allows calling code to handle validation failures differently from runtime errors or network exceptions.
Is ParamError used in non-destructive operations?
Yes. ParamError validates all critical parameters including apiKey, endpoint, serviceId, and various combinations of filter fields. However, the strictest checks apply to methods that delete or clear data.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →