packages/cli-v3/skills/trigger-authoring-tasks/SKILL.md
The full, version-pinned reference for authoring tasks ships inside your installed @trigger.dev/sdk. Read it before writing code — it always matches the SDK version in this project, so it never drifts:
node_modules/@trigger.dev/sdk/skills/trigger-authoring-tasks/SKILL.md — the complete guide (setup, schemaTask, retries, triggering + the Result shape, idempotency, waits, metadata, scheduled tasks, queues/concurrency, trigger.config.ts).node_modules/@trigger.dev/sdk/docs/; the skill above lists the exact pages it draws from in its sources: frontmatter. Grep for an API, e.g. grep -rl "schemaTask" node_modules/@trigger.dev/sdk/docs/.If those paths don't exist, @trigger.dev/sdk isn't installed yet — install it first. In a non-hoisted layout, resolve the package with node -p "require.resolve('@trigger.dev/sdk/package.json')" and read skills/ + docs/ beside it.
Always import from @trigger.dev/sdk — never @trigger.dev/sdk/v3 (deprecated alias) or @trigger.dev/core.
CRITICAL: Treating the wait result as the output. triggerAndWait and wait.forToken return a Result object, not the raw output.
const out = await childTask.triggerAndWait(p); use(out.foo);const r = await childTask.triggerAndWait(p); if (r.ok) use(r.output.foo); (or .unwrap()).Wrapping triggerAndWait / batchTriggerAndWait / wait in Promise.all.
await Promise.all([childTask.triggerAndWait(a), childTask.triggerAndWait(b)]);await childTask.batchTriggerAndWait([{ payload: a }, { payload: b }]); (or a sequential for-loop).Importing the task instance into backend code.
import { emailSequence } from "~/trigger/emails"; in a route handler.import type { emailSequence } plus tasks.trigger<typeof emailSequence>("email-sequence", payload).Calling metadata.set/get outside run().
get returns undefined).run() or a task lifecycle hook.Assuming child tasks inherit the parent's queue or metadata.
concurrencyLimit or see its metadata.{ metadata: metadata.current() }, or push up with metadata.parent.*.Bundling native/WASM packages.
sharp, re2, sqlite3, or WASM packages in the default bundle.build.external in trigger.config.ts.Relying on a raw string idempotency key being global.
trigger(p, { idempotencyKey: "welcome-email" }) expecting once-ever (true only in v4.3.0 and earlier).await idempotencyKeys.create("welcome-email", { scope: "global" }).Sibling skills: trigger-realtime-and-frontend (subscribe to runs, trigger from the frontend), trigger-authoring-chat-agent and trigger-chat-agent-advanced (AI chat agents).