format_not_forkable 409 in the Sume API: what it means and the fix

Sume returns 409 format_not_forkable when the id you called names a built-in capability, not a Format card. How to tell, and which ids to call instead.

4 min readSume
All posts

What does 409 format_not_forkable mean? According to the Sume Formats errors page, it means you addressed a built-in capability rather than a Format, and the fix is to call a Format by Sume or one of your own. A Format is a saved recipe you can address as {handle}/{slug} or by its opaque skl_... id. A built-in capability is something the platform ships that is not packaged as a Format card, so the run endpoints refuse to treat it as one.

You will meet this error when a script builds the address from a list that mixes real Formats with other ids, which is easy to do with a catalog sheet.

Which addresses work

The curated Formats by Sume live under the reserved sume handle, such as sume/sume-product-commercial and sume/sume-video-hook from the catalog, and the API reference says they are directly invokable and never return this error. Your own Formats are {your-handle}/{slug}. Both can be called with POST /v1/formats/{handle}/{slug}/runs and both can be queued with .../bulk-runs.

Handle renames resolve for 90 days, so an old handle still works for a while, but a capability id never will. If a call fails with format_not_forkable it will keep failing: retrying is wasted time.

Triage in four steps

  • Read error.code first. A 409 has several meanings on a run submit, including format_run_in_progress, format_inactive, format_api_trigger_disabled, previous_run_not_terminal and idempotency_conflict.
  • If the code is format_not_forkable, check the id you sent against the Formats you can list with GET /v1/formats.
  • Swap in a sume/{slug} catalog Format, or create your own and call that.
  • Do not retry the same id; the answer will not change.

Where it hides in a pipeline

The usual source is a spreadsheet of identifiers that grew by copy and paste. One row holds a catalog Format, another holds a name that you remember from a product page, and the loop calls them all with the same endpoint. The first call that names a capability returns the 409 and the loop stops or, worse, logs and continues.

Make the failure loud. Treat any 409 with this code as a data error in your list, not as a transient fault, and put the offending id in the alert. In a bulk job the address is part of the URL, so the error shows up on the create call, before a queue exists, and costs nothing.

If you wanted a capability's output, use a Format that wraps it, from the Formats catalog or one you create with POST /v1/formats, then call that.

Guard a bulk job

In a bulk create, a bad address fails the create call before any queue exists, so nothing is dispatched. The check below validates a list of ids against the known shape before the first request goes out: the {handle}/{slug} form, or an skl_ id. It cannot know which ids are capabilities, so keep a list of the ones you have verified.

import re

SHAPE = re.compile(r"^([a-z0-9][a-z0-9-]*/[a-z0-9][a-z0-9-]*|skl_[A-Za-z0-9]+)$")
verified = {"sume/sume-video-hook", "mybrand/holiday-promo"}
requested = ["sume/sume-video-hook", "mybrand/holiday-promo", "Some Capability"]
for ident in requested:
    if not SHAPE.match(ident):
        print("bad shape:", ident)
    elif ident not in verified:
        print("unverified, check before bulk:", ident)
    else:
        print("ok:", ident)

Sources

Related posts

More in Developers

All Developers posts

Written by Sume