Sume MCP conflicting_model: top-level model vs payload.model

avatar-image-to-video_create lifts payload.model to the top level. If the two differ you get conflicting_model plus supported_models. Send one, or match them.

4 min readSume
All posts

On the Sume hosted MCP tool avatar-image-to-video_create, a top-level model and a payload.model that disagree return a conflicting_model error carrying model, payload_model and supported_models. Send the model in one place, or send the same value in both.

Why two places exist

MCP clients and models tend to put arguments next to the tool, while the REST body keeps model inside payload. For paid creates, Sume accepts a small allowlist of top-level keys: allow_paid, allow_write, dry_run, idempotency_key, max_spend_usd, model and payload. For this tool the server lifts the model out of the payload so either spelling works, and it refuses when both are present and different rather than guessing which one you meant.

This is the same churn problem you see when a vendor renames model ids: an old config says one thing, a new prompt says another. The DeepSeek legacy names post covers the vendor side of that; this error is the Sume side.

The two errors

There are two distinct model errors on this tool, and they need different fixes.

Model errors on avatar-image-to-video_create (read 2026-10-05 against the Sume codebase)
Error codeCauseFix
conflicting_modeltop-level model differs from payload.modelsend one, or match both
unsupported_modelmodel not in the tool's listpick from supported_models in the error

Models this tool accepts

The tool's two supported models are veed/fabric-1.0, which is the default, and minimax/h3-max/lip-sync. Do not hard-code these in your agent. The error returns supported_models, and tools_schema returns the live contract, so read it when an id is refused.

def resolve_model(top, payload):
    inner = (payload or {}).get('model')
    if top and inner and top != inner:
        raise ValueError(f'conflicting_model: {top!r} vs {inner!r}')
    return top or inner or 'veed/fabric-1.0'

print(resolve_model(None, {'model': 'minimax/h3-max/lip-sync'}))
print(resolve_model('veed/fabric-1.0', {}))

Handling it in an agent loop

On conflicting_model, do not retry with a random pick. Drop the field you did not intend, keep the same idempotency_key, and resend. The key is safe to reuse because the earlier call was refused before any work started.

Limits: this behavior is specific to the tool that lifts the model. Other paid tools simply reject unknown top-level keys with unsupported_tool_arguments, whose hint tells you to move fields into payload.

A typical failure

A planner built for one model family writes model: "veed/fabric-1.0" beside the payload, because that is how its examples were written. A later prompt edit, made after a vendor rename elsewhere in the stack, adds a different model string inside payload. Neither string is wrong on its own, and each would pass alone. Together they trigger the error, which names both values and lists the supported ones.

The fix belongs in the tool-call builder, not in the model. Have your harness remove model from the top level and carry it only inside payload, then log which one you sent. If a model must be switched at run time, change it in exactly one variable.

Checklist before you ship

  • Pick one home for model in your tool-call builder, ideally inside payload.
  • Read supported_models from the error instead of hard-coding ids in the prompt.
  • Keep the same idempotency_key when you resend after a refused call.
  • Re-read tools_schema after a vendor model rename before editing prompts.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume