ComposioHQ/composio · error · RuntimeError

Could not determine a home directory to store the Composio c

Error message

Could not determine a home directory to store the Composio cache in. Provide a writable path using the {ENV_LOCAL_CACHE_DIRECTORY} environment variable.

What it means

A custom toolkit was constructed without a description. The experimental.Toolkit constructor requires both a name and a non-empty description so custom toolkits can be surfaced and documented server-side; an empty or missing description fails fast with a ValidationError.

Source

Thrown at python/composio/core/models/_files.py:113

def get_cache_directory() -> Path:
    """Resolve the local caching directory without touching the filesystem.

    ``COMPOSIO_CACHE_DIR`` is read on every call, so it can be set after
    ``composio`` has already been imported. ``Path.home()`` is only consulted
    when the variable is unset: it can raise ``RuntimeError`` when there is no
    resolvable home directory, which is exactly the situation
    ``COMPOSIO_CACHE_DIR`` exists to work around, so it must not be evaluated
    eagerly as a fallback argument.
    """
    configured = os.environ.get(ENV_LOCAL_CACHE_DIRECTORY)
    if configured:
        return Path(configured)

    try:
        home = Path.home()
    except RuntimeError as e:
        raise RuntimeError(
            "Could not determine a home directory to store the Composio cache "
            f"in. Provide a writable path using the {ENV_LOCAL_CACHE_DIRECTORY} "
            "environment variable."
        ) from e
    return home / LOCAL_CACHE_DIRECTORY_NAME


def get_output_file_directory() -> Path:
    """Default local directory into which files downloaded during tool
    execution are written. Override by passing ``file_download_dir=...`` to
    Composio, or by setting ``outdir`` on ``FileHelper`` directly.
    """
    return get_cache_directory() / LOCAL_OUTPUT_FILE_DIRECTORY_NAME


def ensure_cache_directory() -> Path:
    """Create the cache directory on first use and check that it is writable.

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Add a meaningful description string to the Toolkit constructor
  2. Check that the variable feeding description isn't None/empty before constructing the toolkit

Example fix

# before
tk = Toolkit(slug='my_tk', name='My Toolkit', description='')
# after
tk = Toolkit(slug='my_tk', name='My Toolkit', description='Tools for managing my app resources')
Defensive patterns

Strategy: validation

Validate before calling

if not description or not description.strip():
    raise ValueError('Toolkit description is required')
tk = Toolkit(slug=slug, name=name, description=description.strip())

Type guard

from composio.core.models.custom_tool import Toolkit

def is_valid_toolkit_def(slug: str, name: str, description: str) -> bool:
    return bool(slug) and bool(name) and bool(description and description.strip())

Try / catch

try:
    tk = Toolkit(slug=s, name=n, description=d)
except ValidationError as e:
    if 'description is required' in str(e):
        d = 'Custom toolkit for ' + n
        tk = Toolkit(slug=s, name=n, description=d)
    else:
        raise

Prevention

When it happens

Trigger: Creating experimental.Toolkit(slug=..., name=..., description='') or passing description=None when defining a custom toolkit in the Python SDK.

Common situations: Copying a toolkit template and forgetting the description field; assuming description is optional like other kwargs; passing an empty string after stripping user input.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/97d152f458f7cdbe. Report an issue: GitHub.