Storage & JSON Types
The SDK exports two types that describe JSON-serializable data: JsonValue and
JsonObject. They are the foundation of ctx.storage, the persistent state available to a
task across runs.
JsonValue
type JsonValue =
| null
| boolean
| number
| string
| JsonValue[]
| { [key: string]: JsonValue }These are the JSON data types. This excludes undefined, functions, BigInt,
Date, and other non-JSON types.
JsonObject
type JsonObject = { [key: string]: JsonValue }A plain object whose values are all JsonValues. This is the type of ctx.storage.
The storage mutation pattern
ctx.storage is a mutable JsonObject persisted across runs of the same executable.
Mutate it in place. The platform commits eligible writes after a skip or successful execution; a failed run discards its pending writes:
ctx.storage.runs = ((ctx.storage.runs as number | undefined) ?? 0) + 1Because JsonValue is broad, validate the field shape when reading data written by earlier versions or edited externally:
const stored = ctx.storage.seen
const seen = Array.isArray(stored)
? stored.filter((value): value is string => typeof value === 'string')
: []
seen.push(latestId)
ctx.storage.seen = seenA counter task that only updates state and never executes:
import { defineTask, z } from '@thyme-labs/sdk'
export default defineTask({
schema: z.object({}),
async run(ctx) {
ctx.storage.runs = ((ctx.storage.runs as number | undefined) ?? 0) + 1
return { canExec: false, message: 'State updated' }
},
})Rules
- Plain JSON object only — values must be
JsonValue. - No
undefined,NaN,Infinity, or-0. - Forbidden keys:
__proto__,constructor,prototype. - 100 MiB total size cap.
Local vs cloud persistence
- Local (
thyme run): seeded fromfunctions/<task>/storage.json, printed after the run, and only written back when you pass--persist. - Cloud: stored per-executable with optimistic versioning and a per-run lock, so only one run mutates at a time. Editable from the executable detail panel and the management API. Management storage requests have their own smaller transport limit; the 100 MiB stored-value limit is not the size accepted by every endpoint.
Store bigint values as decimal strings and dates as ISO strings. See Storage for commit/version behavior and lifecycle callbacks for callback storage snapshots.
Related
- ThymeContext —
ctx.storagein context. - Storage — persistence model and editing in the Console.