agalwood/Motrix · error · StorageError
plugin.storage.value_not_serializable
plugin.storage.value_not_serializable
Error message
plugin.storage.value_not_serializable: undefined is not JSON-serializable
What it means
Storage capability mirror of 112. The top-level value passed to storage set() is undefined, and serialize() short-circuits with an explicit typed error rather than letting JSON.stringify silently drop it. Same value shape, different capability namespace (plugin.storage vs plugin.metadata).
Source
Thrown at src/core/plugin/capabilities/storage.ts:78
constructor(
public readonly code: string,
message: string
) {
super(message)
this.name = 'StorageError'
}
}
/**
* Serialize `value` to JSON.
* Throws `plugin.storage.value_not_serializable` when:
* - the value is top-level `undefined`
* - JSON.stringify returns undefined (e.g. a plain function)
* - JSON.stringify throws (e.g. BigInt, class with throwing toJSON)
*/
function serialize(value: unknown): string {
if (value === undefined) {
throw new StorageError(
'plugin.storage.value_not_serializable',
'plugin.storage.value_not_serializable: undefined is not JSON-serializable'
)
}
let json: string | undefined
try {
json = JSON.stringify(value)
} catch {
throw new StorageError(
'plugin.storage.value_not_serializable',
'plugin.storage.value_not_serializable: value cannot be serialized to JSON'
)
}
if (json === undefined) {
throw new StorageError(
'plugin.storage.value_not_serializable',
'plugin.storage.value_not_serializable: value cannot be serialized to JSON'
)View on GitHub (pinned to 1a708ee577)
Solutions
- Use null to represent absence rather than undefined.
- Skip the set() call when the value is undefined.
- Default the value at the source with ?? null or ?? {}.
Example fix
// before await storage.set(key, maybeValue) // after if (maybeValue !== undefined) await storage.set(key, maybeValue)
Defensive patterns
Strategy: validation
Validate before calling
if (value === undefined) throw new Error('storage value required')
await storage.set(key, value) Type guard
function isDefined<T>(v: T | undefined): v is T { return v !== undefined } Prevention
- Represent absence with null rather than undefined in stored values.
- Skip the set() call when the value is undefined.
- Constrain settable values to a JSONValue type so undefined is rejected at compile time.
When it happens
Trigger: Calling storage.set(key, undefined); a variable that conditionally ended up undefined; refactor left a placeholder; plugin reads an optional env/config value and passes it through without a default.
Common situations: Plugin stores the result of an optional lookup; defaulting missing; TypeScript optional property accessed without nullish-coalescing.
Related errors
- plugin.metadata.value_not_serializable
- IpcInvalidPayload
- taskId must be a string
- Key must be 16 bytes, got ${key.length}
- IV must be 16 bytes, got ${iv.length}
AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12).
Data as JSON: /api/errors/5f2158751fafae1c.
Report an issue: GitHub.