microsoft/semantic-kernel · error · TypeError

"{self.config_key}" not found in configuration.

Error message

"{self.config_key}" not found in configuration.

What it means

A TypeError raised when the Config object exists but has no ALLOWED_CALLERS attribute (getattr returns None). The validator derives its allowed-caller set from config.ALLOWED_CALLERS; if that setting is absent the frozenset cannot be built and authorization cannot be enforced.

Source

Thrown at python/samples/demos/copilot_studio_skill/src/api/auth.py:23

from botframework.connector.auth import JwtTokenValidation, SkillValidation
from config import Config


class AllowedCallersClaimsValidator:
    config_key = "ALLOWED_CALLERS"

    def __init__(self, config: Config):
        if not config:
            raise TypeError("AllowedCallersClaimsValidator: config object cannot be None.")

        # ALLOWED_CALLERS is the setting in config.py file
        # that consists of the list of parent bot ids that are allowed to access the skill
        # to add a new parent bot simply go to the AllowedCallers and add
        # the parent bot's microsoft app id to the list
        caller_list = getattr(config, self.config_key)
        if caller_list is None:
            raise TypeError(f'"{self.config_key}" not found in configuration.')
        self._allowed_callers = frozenset(caller_list)

    @property
    def claims_validator(self) -> Callable[[list[dict]], Awaitable]:
        async def allow_callers_claims_validator(claims: dict[str, object]):
            # if allowed_callers is None we allow all calls
            if "*" not in self._allowed_callers and SkillValidation.is_skill_claim(claims):
                # Check that the appId claim in the skill request is in the list of skills configured for this bot.
                app_id = JwtTokenValidation.get_app_id_from_claims(claims)
                if app_id not in self._allowed_callers:
                    raise PermissionError(
                        f'Received a request from a bot with an app ID of "{app_id}".'
                        f" To enable requests from this caller, add the app ID to your configuration file."
                    )

            return

        return allow_callers_claims_validator

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure Config defines ALLOWED_CALLERS (the sample defaults it to ['*'] via os.getenv).
  2. Set the ALLOWED_CALLERS env var, or '*' to allow all callers.
  3. Restore the field on the Config class if it was removed during customization.

Example fix

// before
class Config:
    HOST = os.getenv("HOST")
    # ALLOWED_CALLERS missing

// after
class Config:
    HOST = os.getenv("HOST")
    ALLOWED_CALLERS = os.getenv("ALLOWED_CALLERS", ["*"])
Defensive patterns

Strategy: validation

Validate before calling

from config import config
if getattr(config, 'ALLOWED_CALLERS', None) is None:
    raise SystemExit("Config.ALLOWED_CALLERS is missing; set ALLOWED_CALLERS env var.")

Type guard

def config_has_allowed_callers(cfg) -> bool:
    return getattr(cfg, 'ALLOWED_CALLERS', None) is not None

Prevention

When it happens

Trigger: Constructing AllowedCallersClaimsValidator with a Config class/instance whose ALLOWED_CALLERS is None — e.g. a custom Config that omits the field, or ALLOWED_CALLERS env var unset with no default.

Common situations: Using a Config subclass without ALLOWED_CALLERS; the env var was unset and the Config default was removed; copy-paste config that dropped the field.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/271f7f9ef25a4474. Report an issue: GitHub.