langchain-ai/deepagents · error · RuntimeError

Failed to read credential file {path}: {exc}. Check the file

Error message

Failed to read credential file {path}: {exc}. Check the file permissions on the parent directory.

What it means

`_read_raw` wraps OSError while reading the credential file and re-raises it as a RuntimeError telling the user to check parent-directory permissions. This converts OS-level failures (missing file access, permission errors) into a consistent, actionable error for `load_credentials`, `set_stored_key`, and `delete_stored_key`.

Source

Thrown at libs/code/deepagents_code/auth_store.py:179

    Returns:
        The decoded JSON object, or `None` when the file is missing.

    Raises:
        RuntimeError: If the file exists but cannot be parsed or has an
            unsupported schema version.
    """
    path = auth_path()
    try:
        raw = path.read_text(encoding="utf-8")
        data = json.loads(raw)
    except FileNotFoundError:
        return None
    except OSError as exc:
        msg = (
            f"Failed to read credential file {path}: {exc}. "
            "Check the file permissions on the parent directory."
        )
        raise RuntimeError(msg) from exc
    except (UnicodeDecodeError, json.JSONDecodeError) as exc:
        # `UnicodeDecodeError` (a `ValueError`, not an `OSError`) escapes the
        # handler above when the file holds non-UTF-8 bytes; treat a decode
        # failure as corruption so callers get the same `RuntimeError` hint
        # instead of an unhandled traceback.
        msg = (
            f"Failed to parse credential file {path}: {exc}. "
            "Delete the file and re-add credentials via /auth if it is corrupt."
        )
        raise RuntimeError(msg) from exc
    if not isinstance(data, dict):
        msg = (
            f"Credential file {path} is not a JSON object. "
            "Delete it and re-add credentials via /auth."
        )
        # `RuntimeError` (not `TypeError`) is intentional: every corruption
        # path here surfaces the same error class so callers can render one
        # remediation hint regardless of the specific shape problem.

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Fix permissions: chown -R $(whoami) ~/.config/<app> and ensure the directory is readable/writable
  2. Check parent-directory permissions (ls -la on the credentials dir) per the error hint
  3. If the file is corrupt/unrecoverable, delete it and re-authenticate
  4. Run the app as the user who owns the credential file

Example fix

// before (shell)
cat ~/.config/deepagents/credentials   # PermissionError
// after
sudo chown -R $(whoami) ~/.config/deepagents && chmod 700 ~/.config/deepagents
Defensive patterns

Strategy: try-catch

Validate before calling

import os
cred_dir = os.path.dirname(path)
if not os.access(cred_dir, os.R_OK | os.X_OK):
    raise RuntimeError(f"no access to credentials directory: {cred_dir}")

Try / catch

try:
    creds = load_credentials()
except RuntimeError as exc:
    if "Failed to read credential file" in str(exc):
        logger.error("fix permissions on the credentials directory, then re-authenticate: %s", exc)
    raise

Prevention

When it happens

Trigger: Reading the auth-store file fails with an OSError: restrictive file modes (chmod 000), a parent directory without read permission, the file being locked/deleted mid-read, or running under a different user/container without ownership of the credentials directory.

Common situations: CI containers running as non-root against a home dir mounted from the host; switching users via sudo so ~/.config ownership no longer matches; read-only or corrupted mounts.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/aae6893a914184e9. Report an issue: GitHub.