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
- Remove one of the two arguments: pass only github_token OR only github_token_provider to create_session.
- If you need dynamic token refresh, drop the static github_token and keep github_token_provider.
- If a static token is sufficient, drop github_token_provider and keep github_token.
- 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
- Never pass both github_token and github_token_provider in the same call.
- Centralize credential selection in one helper that picks exactly one source.
- Review wrappers/helpers that forward credential kwargs blindly.
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
- Set environment variables via either the client-level env…
- Client is not connected. Call start() first.
- telemetry is not supported with…
- connectionToken must be a non-empty string
- GitHubToken and GitHubTokenProvider cannot be used together.
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)