ComposioHQ/composio · error · ValueError
schema is unsatisfiable (JSON Schema `false`)
Error message
schema is unsatisfiable (JSON Schema `false`)
What it means
Raised when a JSON Schema contains the boolean schema `false` (which accepts no value at all) and something then attempts to validate a value against the converted Pydantic model. schema_converter.py models `false` with a _UnsatisfiableSchema Pydantic type whose validator always raises ValueError, so any validated input fails. It usually indicates the upstream tool/action schema was authored incorrectly or transformed into `false` during conversion.
Source
Thrown at python/composio/utils/schema_converter.py:52
from pydantic import (
create_model as create_pydantic_model,
)
from pydantic_core import core_schema
from composio.utils.logging import get as get_logger
logger = get_logger(__name__)
_MISSING = object()
_EXPLICIT_DEFAULT_FIELDS_ATTRIBUTE = "__composio_explicit_default_fields__"
class _UnsatisfiableSchema:
"""Pydantic type for JSON schemas that reject every value."""
@staticmethod
def _reject(_value: t.Any) -> t.NoReturn:
raise ValueError("schema is unsatisfiable (JSON Schema `false`)")
@classmethod
def __get_pydantic_core_schema__(
cls,
_source_type: t.Any,
_handler: t.Any,
) -> core_schema.CoreSchema:
return core_schema.no_info_plain_validator_function(cls._reject)
@classmethod
def __get_pydantic_json_schema__(
cls,
_core_schema: core_schema.CoreSchema,
_handler: t.Any,
) -> t.Dict[str, t.Any]:
return {"not": {}}
View on GitHub (pinned to 64b1b85502)
Solutions
- Inspect the tool's input schema (print the raw schema from the API) and locate the boolean `false` node — fix or remove it at the source (tool definition or OpenAPI spec)
- If the false schema is nested via $ref, fix the referenced definition so it is a real object schema
- Guard model construction: skip tools whose converted model is _UnsatisfiableSchema instead of validating inputs
- Report/regenerate the tool schema if it comes from Composio's backend (generated client pin may need a bump)
Example fix
// before (schema fragment)
{"properties": {"disabled_opt": false}}
// after
{"properties": {"disabled_opt": {"type": "string"}}} Defensive patterns
Strategy: validation
Validate before calling
def is_satisfiable(schema) -> bool:
if schema is False:
return False
if isinstance(schema, dict):
return all(is_satisfiable(v) for v in schema.values())
if isinstance(schema, list):
return all(is_satisfiable(i) for i in schema)
return True
assert is_satisfiable(tool_input_schema) Type guard
from composio.utils.schema_converter import _UnsatisfiableSchema
def is_unsatisfiable_model(model) -> bool:
return model is _UnsatisfiableSchema Try / catch
try:
model.validate(args)
except ValueError as e:
if "unsatisfiable" in str(e):
skip_tool(tool) # schema bug, not caller error Prevention
- Sanitize incoming tool schemas for boolean `false` nodes before conversion
- Skip and report tools whose converted model is the unsatisfiable type
- Pin generated client versions after verifying schemas convert cleanly
When it happens
Trigger: Calling .validate(value) (or Pydantic validation) on a converted model whose schema (or a subschema reached via $ref/anyOf items) is literally boolean false. Happens when a tool definition contains "type": false, an unreachable anyOf/oneOf branch collapsed to false, or a properties entry set to false.
Common situations: Backend-generated tool schemas with a `false` placeholder for disabled parameters; hand-written OpenAPI specs using bare `false` for "no value allowed"; schema transformations that reduce impossible constraints to false; version drift after a generated client bump introducing false schemas.
Related errors
- {error.message}
- Unrecognized key(s) in object: {', '.join(repr(key) for key
- Tool schema nesting exceeded the maximum supported depth (${
- Tool arguments nesting exceeded the maximum supported depth
- Expected a z.object() schema.
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/87e18417b2f19b4f.
Report an issue: GitHub.