Skip to content
skyl

Unsupportedf

Builds an ErrUnsupported naming exactly what could not be represented.

Adapters use Unsupportedf instead of silently dropping data they cannot express. The formatted message is the point: it tells the caller precisely which part failed, so they can fix it rather than guess.

Reference#

func Unsupportedf(provider, format string, args ...any) error

Parameters

  • provider — the adapter's name.
  • format, args — a fmt-style message naming what could not be represented.

Returns

An *Error with Kind: ErrUnsupported, no status code, and the formatted message.

Caveats

  • It is normally returned before any network call, so it costs nothing.
  • Retryable() returns false — a provider that structurally cannot express something will not be able to on a second attempt.
  • Client.Models treats it specially and does not retry it at all.
  • Name the specific thing. "unsupported" tells the caller nothing they did not already know from the sentinel.

Usage#

Rejecting a part an adapter cannot render

goCompiles
if img.URL != "" {
	// Name the constraint, so the caller knows what to change.
	return nil, skyl.Unsupportedf(p.Name(),
		"Gemini requires inline image data, not a URL")
}
if img.URL != "" {
	// Name the constraint, so the caller knows what to change.
	return nil, skyl.Unsupportedf(p.Name(),
		"Gemini requires inline image data, not a URL")
}

Naming a role restriction

if m.Role == skyl.RoleTool {
	if _, isText := part.(skyl.Text); isText {
		return nil, skyl.Unsupportedf(p.Name(),
			"tool messages may only contain tool results")
	}
}
if m.Role == skyl.RoleTool {
	if _, isText := part.(skyl.Text); isText {
		return nil, skyl.Unsupportedf(p.Name(),
			"tool messages may only contain tool results")
	}
}

Reporting it to a user

goCompiles
var e *skyl.Error
if errors.As(err, &e) && errors.Is(err, skyl.ErrUnsupported) {
	// The message is specific enough to show directly.
	return fmt.Errorf("this model (%s) cannot handle that input: %s", e.Provider, e.Message)
}
var e *skyl.Error
if errors.As(err, &e) && errors.Is(err, skyl.ErrUnsupported) {
	// The message is specific enough to show directly.
	return fmt.Errorf("this model (%s) cannot handle that input: %s", e.Provider, e.Message)
}

Troubleshooting#

Should my adapter drop the data instead?

No. Silent data loss is the worst failure mode this library has — a dropped image looks exactly like a model that ignored the question, and the caller will spend an afternoon on the prompt before suspecting the transport.

Should I return this for a feature the provider might add later?

Yes. It is the honest answer today, and it costs the caller one line to route around via ProviderOptions. Pretending support exists is worse.

Edit this page on GitHub