github/copilot-sdk · error

Invalid entry '*': there is no bare wildcard. Use one or…

Error message

Invalid ${field} entry '*': there is no bare wildcard. Use one or more of `new ToolSet().addBuiltIn('*')`, `.addMcp('*')`, or `.addCustom('*')` to target a specific source.

What it means

CopilotClient.create_session() raises this ValueError when both github_token and github_token_provider arguments are supplied. The two options are alternative ways to supply GitHub credentials - a static token string or a dynamic provider callable/object - and the library cannot honor both at once, so it fails fast at argument-validation time before any session is created.

Solutions

  1. Remove one of the two arguments: pass only github_token OR only github_token_provider to create_session.
  2. If you need dynamic token refresh, drop the static github_token and keep github_token_provider.
  3. If a static token is sufficient, drop github_token_provider and keep github_token.
  4. If arguments come from a shared config, assert exactly one of the two is set before calling the API.

Example fix

// before
await client.create_session(
    github_token=os.environ["GH_TOKEN"],
    github_token_provider=my_provider,
)
// after
await client.create_session(
    github_token_provider=my_provider,
)
Defensive patterns

Strategy: validation

Validate before calling

if github_token is not None and github_token_provider is not None:
    raise ValueError("Pass either github_token or github_token_provider, not both")

Type guard

def has_conflicting_credentials(kwargs: dict) -> bool:
    return kwargs.get("github_token") is not None and kwargs.get("github_token_provider") is not None

Try / catch

try:
    await client.create_session(...)
except ValueError as e:
    if "mutually exclusive" in str(e):
        ...  # drop one credential option and retry

Prevention

When it happens

Trigger: Calling create_session(...) with both a github_token string and a github_token_provider set (both not None). Also occurs when config objects or wrappers merge credential fields from multiple sources into one call.

Common situations: Migrating code from a static token to a provider-based token while leaving the old github_token argument in place; a factory function that forwards optional credential parameters and sets both; examples/tests where env vars supply one option and code supplies the other.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/4e9d1352892ce8b0. Report an issue: GitHub.

Appendix: source

Thrown at nodejs/src/client.ts:319

}

/**
 * Catches misuse of `availableTools`/`excludedTools` at the SDK boundary so
 * users get an actionable error rather than a silently-empty filter.
 *
 * The runtime treats a bare `"*"` as a literal name match for a tool whose
 * name is the single character `*`, which the runtime's charset guard would
 * reject at registration — so the filter effectively matches nothing. We
 * surface that here as an error pointing the developer at the source-qualified
 * forms produced by {@link ToolSet}.
 */
function validateToolFilterList(field: string, list: string[] | undefined): void {
    if (!list) {
        return;
    }
    for (const entry of list) {
        if (entry === "*") {
            throw new Error(
                `Invalid ${field} entry '*': there is no bare wildcard. ` +
                    "Use one or more of `new ToolSet().addBuiltIn('*')`, `.addMcp('*')`, " +
                    "or `.addCustom('*')` to target a specific source."
            );
        }
    }
}

/**
 * Extract transform callbacks from a system message config and prepare the wire payload.
 * Function-valued actions are replaced with `{ action: "transform" }` for serialization,
 * and the original callbacks are returned in a separate map.
 */
function extractTransformCallbacks(systemMessage: SessionConfig["systemMessage"]): {
    wirePayload: SessionConfig["systemMessage"];
    transformCallbacks: Map<string, SectionTransformFn> | undefined;
} {
    if (!systemMessage || systemMessage.mode !== "customize" || !systemMessage.sections) {

View on GitHub (pinned to cd8cf15dc3)