Migrating to v3
Run the codemods, then finish anything reported as not migrated automatically:
npx @tailor-platform/sdk-codemod --from <current-version> --to <target-version>workflow.execJobFunction (imported) removed — use job.start()
Migration: Manual
execJobFunction on the workflow value imported from @tailor-platform/sdk/runtime(/workflow) is removed in v3. Calling it directly from a workflow job body to reach another job is not detected as a build-time dependency and has no working use; the target job's own .start() method is the only supported way to call it. This does not affect the ambient tailor.workflow.execJobFunction global — that's what .start() itself compiles down to at build time, and it remains fully supported.
Before:
import { workflow } from "@tailor-platform/sdk/runtime";
await workflow.execJobFunction("worker", { id: 1 });After:
import { worker } from "./jobs/worker";
await worker.start({ id: 1 });Prompt for an AI agent (to perform this migration)
workflow.execJobFunction — the value imported from
@tailor-platform/sdk/runtime or @tailor-platform/sdk/runtime/workflow — is
removed in v3. Replace each call with the target job's own .start() method:
import the WorkflowJob the call names and call <job>.start(args, options)
instead of workflow.execJobFunction("<job-name>", args, options).
This only removes the re-export from @tailor-platform/sdk/runtime. It does
not affect the ambient tailor.workflow.execJobFunction global, which stays
fully supported and is what .start() itself compiles down to at build time.
This codemod does not rewrite ambient tailor.workflow.execJobFunction(...)
call sites, since removing the import re-export does not affect them — but
if such a call site sits inside workflow job source and calls another job
by name, a separate build-time check already rejects it; migrate that call
to the target job's own .start() method too.
If the job name passed to execJobFunction is not a string literal (a truly
dynamic dispatch), there is currently no supported replacement — .start()
only targets a statically known job. Flag this case for a human instead of
guessing a rewrite.function test-run → function run
Migration: Partially automatic
Rename tailor function test-run invocations to tailor function run. test-run remains as a deprecated alias until it is removed in v3.
Before:
tailor function test-run resolvers/add.ts --arg '{"a":1,"b":2}'After:
tailor function run resolvers/add.ts --arg '{"a":1,"b":2}'Prompt for an AI agent (to finish the cases the codemod could not migrate)
The `tailor function test-run` subcommand is renamed to `tailor function run`;
the old name is removed in v3. Replace any remaining `function test-run`
invocations the codemod did not rewrite (e.g. wrapped across lines or invoked
through a package runner such as `npx @tailor-platform/sdk`) with
`function run`. Leave prose that merely mentions the old subcommand name
unchanged unless it documents a command to type.setup branch --branch → --target
Migration: Partially automatic
Rename the --branch option of tailor setup branch invocations to --target. --branch remains as a deprecated alias until it is removed in v3. The --branch option of setup tag, setup preview, and setup coordinate is unchanged.
Before:
tailor setup branch --name my-app-stg --branch mainAfter:
tailor setup branch --name my-app-stg --target mainPrompt for an AI agent (to finish the cases the codemod could not migrate)
The `--branch` option of `tailor setup branch` is renamed to `--target`;
the old spelling is removed in v3. Replace any remaining `--branch` options of
`setup branch` invocations the codemod did not rewrite (e.g. wrapped across
lines or invoked through a package runner such as `npx @tailor-platform/sdk`)
with `--target`. Do not touch the `--branch` option of `setup tag`,
`setup preview`, or `setup coordinate`, which keeps its name, and leave prose
that merely mentions the option unchanged unless it documents a command to type.relation() toward.type → toward.table
Migration: Partially automatic
Rename the .relation() option toward.type to toward.table, matching the db.type() → db.table() rename. The relation's own type (its cardinality, e.g. "n-1") is unchanged — only the target-table reference nested under toward moves.
Before:
customerId: db.uuid().relation({
type: "n-1",
toward: { type: customer },
}),After:
customerId: db.uuid().relation({
type: "n-1",
toward: { table: customer },
}),Prompt for an AI agent (to finish the cases the codemod could not migrate)
In Tailor SDK v3, `.relation()`'s `toward.type` option is renamed to
`toward.table` (it names a target table, not a TypeScript/GraphQL type).
Rename any remaining `toward.type` the codemod did not rewrite (e.g. a
`toward` object reached through a shared variable, spread, or computed
key) to `toward.table`. Do not touch the relation's own outer `type`
property, which is the relation's cardinality (e.g. "n-1", "1-1",
"keyOnly") and keeps its name.String file uploads → explicit encoding
Migration: Manual
String inputs to the SDK file.upload and generated uploadFile require an explicit encoding in v3. Add encoding: "utf8" to preserve the previous behavior; use "base64" only when decoding the input is intended. Byte inputs are unchanged. This migration requires checking the input type and regenerating file helpers, so it provides review guidance instead of rewriting calls automatically.
Before:
await file.upload(ns, table, field, id, text, { contentType: "text/plain" });After:
await file.upload(ns, table, field, id, text, { contentType: "text/plain", encoding: "utf8" });Prompt for an AI agent (to perform this migration)
Inspect calls to the imported SDK file.upload (including aliases and destructured upload)
and generated uploadFile helpers, including shared wrappers and option objects.
For string inputs, add encoding: utf8 to preserve existing text storage behavior.
Choose encoding: base64 only if decoding is explicitly intended; never infer it from
the string contents or contentType. Preserve all existing upload options.
Leave byte-only inputs unchanged. For string | byte unions, supplying encoding: utf8
preserves behavior because byte input ignores encoding. Narrow shared options types
so TypeScript can see that encoding is present for strings.
Run tailor generate to regenerate uploadFile helpers instead of editing generated files.
The global tailordb.file.upload does not support this encoding option; switch to the
file import from @tailor-platform/sdk/runtime before using it.
Do not change unrelated upload APIs or already explicit encodings.